summaryrefslogtreecommitdiffstats
path: root/src/datavisualizationqml
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualizationqml')
-rw-r--r--src/datavisualizationqml/CMakeLists.txt55
-rw-r--r--src/datavisualizationqml/abstractdeclarative.cpp832
-rw-r--r--src/datavisualizationqml/abstractdeclarative_p.h318
-rw-r--r--src/datavisualizationqml/colorgradient.cpp88
-rw-r--r--src/datavisualizationqml/colorgradient_p.h105
-rw-r--r--src/datavisualizationqml/declarativebars.cpp233
-rw-r--r--src/datavisualizationqml/declarativebars_p.h130
-rw-r--r--src/datavisualizationqml/declarativecolor.cpp52
-rw-r--r--src/datavisualizationqml/declarativecolor_p.h72
-rw-r--r--src/datavisualizationqml/declarativerendernode.cpp183
-rw-r--r--src/datavisualizationqml/declarativerendernode_p.h102
-rw-r--r--src/datavisualizationqml/declarativescatter.cpp152
-rw-r--r--src/datavisualizationqml/declarativescatter_p.h102
-rw-r--r--src/datavisualizationqml/declarativescene.cpp60
-rw-r--r--src/datavisualizationqml/declarativescene_p.h76
-rw-r--r--src/datavisualizationqml/declarativeseries.cpp362
-rw-r--r--src/datavisualizationqml/declarativeseries_p.h211
-rw-r--r--src/datavisualizationqml/declarativesurface.cpp164
-rw-r--r--src/datavisualizationqml/declarativesurface_p.h106
-rw-r--r--src/datavisualizationqml/declarativetheme.cpp412
-rw-r--r--src/datavisualizationqml/declarativetheme_p.h143
-rw-r--r--src/datavisualizationqml/designer/Bars3DSpecifics.qml413
-rw-r--r--src/datavisualizationqml/designer/Scatter3DSpecifics.qml209
-rw-r--r--src/datavisualizationqml/designer/Surface3DSpecifics.qml350
-rw-r--r--src/datavisualizationqml/designer/default/Bars3D.qml49
-rw-r--r--src/datavisualizationqml/designer/default/Scatter3D.qml49
-rw-r--r--src/datavisualizationqml/designer/default/Surface3D.qml50
-rw-r--r--src/datavisualizationqml/designer/images/bars3d-icon.pngbin0 -> 1352 bytes
-rw-r--r--src/datavisualizationqml/designer/images/bars3d-icon16.pngbin0 -> 1232 bytes
-rw-r--r--src/datavisualizationqml/designer/images/scatter3d-icon.pngbin0 -> 1271 bytes
-rw-r--r--src/datavisualizationqml/designer/images/scatter3d-icon16.pngbin0 -> 1146 bytes
-rw-r--r--src/datavisualizationqml/designer/images/surface3d-icon.pngbin0 -> 1413 bytes
-rw-r--r--src/datavisualizationqml/designer/images/surface3d-icon16.pngbin0 -> 1231 bytes
-rw-r--r--src/datavisualizationqml/designer/qtdatavisualization.metainfo44
-rw-r--r--src/datavisualizationqml/enumtostringmap.cpp413
-rw-r--r--src/datavisualizationqml/enumtostringmap_p.h64
-rw-r--r--src/datavisualizationqml/foreigntypes_p.h147
-rw-r--r--src/datavisualizationqml/glstatestore.cpp393
-rw-r--r--src/datavisualizationqml/glstatestore_p.h105
39 files changed, 6244 insertions, 0 deletions
diff --git a/src/datavisualizationqml/CMakeLists.txt b/src/datavisualizationqml/CMakeLists.txt
new file mode 100644
index 00000000..4c673a6f
--- /dev/null
+++ b/src/datavisualizationqml/CMakeLists.txt
@@ -0,0 +1,55 @@
+set(qml_files
+ "designer/Bars3DSpecifics.qml"
+ "designer/Scatter3DSpecifics.qml"
+ "designer/Surface3DSpecifics.qml"
+ "designer/default/Bars3D.qml"
+ "designer/default/Scatter3D.qml"
+ "designer/default/Surface3D.qml"
+ "designer/qtdatavisualization.metainfo"
+ "designer/images/bars3d-icon.png"
+ "designer/images/bars3d-icon16.png"
+ "designer/images/scatter3d-icon.png"
+ "designer/images/scatter3d-icon16.png"
+ "designer/images/surface3d-icon.png"
+ "designer/images/surface3d-icon16.png"
+)
+
+set_source_files_properties(${qml_files} PROPERTIES
+ QT_QML_SKIP_QMLDIR_ENTRY TRUE
+)
+
+qt_internal_add_qml_module(DataVisualizationQml
+ URI "QtDataVisualization"
+ VERSION "${PROJECT_VERSION}"
+ PAST_MAJOR_VERSIONS 1
+ DEPENDENCIES
+ QtQuick
+ SOURCES
+ abstractdeclarative.cpp abstractdeclarative_p.h
+ colorgradient.cpp colorgradient_p.h
+ declarativebars.cpp declarativebars_p.h
+ declarativecolor.cpp declarativecolor_p.h
+ declarativerendernode.cpp declarativerendernode_p.h
+ declarativescatter.cpp declarativescatter_p.h
+ declarativescene.cpp declarativescene_p.h
+ declarativeseries.cpp declarativeseries_p.h
+ declarativesurface.cpp declarativesurface_p.h
+ declarativetheme.cpp declarativetheme_p.h
+ enumtostringmap.cpp enumtostringmap_p.h
+ foreigntypes_p.h
+ glstatestore.cpp glstatestore_p.h
+ QML_FILES
+ ${qml_files}
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::Gui
+ Qt::OpenGL
+ Qt::Qml
+ Qt::Quick
+ DataVisualizationPrivate
+)
+
+qt_internal_extend_target(DataVisualizationQml CONDITION MACOS
+ PUBLIC_LIBRARIES
+ Qt::GuiPrivate
+)
diff --git a/src/datavisualizationqml/abstractdeclarative.cpp b/src/datavisualizationqml/abstractdeclarative.cpp
new file mode 100644
index 00000000..dbbd803d
--- /dev/null
+++ b/src/datavisualizationqml/abstractdeclarative.cpp
@@ -0,0 +1,832 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "abstractdeclarative_p.h"
+#include "declarativetheme_p.h"
+#include "declarativerendernode_p.h"
+#include <QtGui/QGuiApplication>
+#if defined(Q_OS_IOS)
+#include <QtCore/QTimer>
+#endif
+#if defined(Q_OS_OSX)
+#include <qpa/qplatformnativeinterface.h>
+#endif
+
+#if !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT)
+#define USE_SHARED_CONTEXT
+#else
+#include "glstatestore_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static QHash<AbstractDeclarative *, QQuickWindow *> graphWindowList;
+
+AbstractDeclarative::AbstractDeclarative(QQuickItem *parent) :
+ QQuickItem(parent),
+ m_controller(0),
+ m_contextWindow(0),
+ m_renderMode(RenderIndirect),
+ m_samples(0),
+ m_windowSamples(0),
+ m_initialisedSize(0, 0),
+ m_contextOrStateStore(0),
+ m_qtContext(0),
+ m_mainThread(QThread::currentThread()),
+ m_contextThread(0)
+{
+ m_nodeMutex = QSharedPointer<QMutex>::create();
+
+ connect(this, &QQuickItem::windowChanged, this, &AbstractDeclarative::handleWindowChanged);
+
+ // Set contents to false in case we are in qml designer to make component look nice
+ m_runningInDesigner = QGuiApplication::applicationDisplayName() == "Qml2Puppet";
+ setFlag(ItemHasContents, !m_runningInDesigner);
+}
+
+AbstractDeclarative::~AbstractDeclarative()
+{
+ destroyContext();
+
+ disconnect(this, 0, this, 0);
+ checkWindowList(0);
+
+ // Make sure not deleting locked mutex
+ QMutexLocker locker(&m_mutex);
+ locker.unlock();
+
+ m_nodeMutex.clear();
+}
+
+void AbstractDeclarative::setRenderingMode(AbstractDeclarative::RenderingMode mode)
+{
+ if (mode == m_renderMode)
+ return;
+
+ RenderingMode previousMode = m_renderMode;
+
+ m_renderMode = mode;
+
+ QQuickWindow *win = window();
+
+ switch (mode) {
+ case RenderDirectToBackground:
+ // Intentional flowthrough
+ case RenderDirectToBackground_NoClear:
+ m_initialisedSize = QSize(0, 0);
+ if (previousMode == RenderIndirect) {
+ update();
+ setFlag(ItemHasContents, false);
+ if (win) {
+ QObject::connect(win, &QQuickWindow::beforeRenderPassRecording, this,
+ &AbstractDeclarative::render, Qt::DirectConnection);
+ checkWindowList(win);
+ setAntialiasing(m_windowSamples > 0);
+ if (m_windowSamples != m_samples)
+ emit msaaSamplesChanged(m_windowSamples);
+ }
+ }
+ break;
+ case RenderIndirect:
+ m_initialisedSize = QSize(0, 0);
+ setFlag(ItemHasContents, !m_runningInDesigner);
+ update();
+ if (win) {
+ QObject::disconnect(win, &QQuickWindow::beforeRenderPassRecording, this,
+ &AbstractDeclarative::render);
+ checkWindowList(win);
+ }
+ setAntialiasing(m_samples > 0);
+ if (m_windowSamples != m_samples)
+ emit msaaSamplesChanged(m_samples);
+ break;
+ }
+
+ updateWindowParameters();
+
+ emit renderingModeChanged(mode);
+}
+
+AbstractDeclarative::RenderingMode AbstractDeclarative::renderingMode() const
+{
+ return m_renderMode;
+}
+
+QSGNode *AbstractDeclarative::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QSize boundingSize = boundingRect().size().toSize() * m_controller->scene()->devicePixelRatio();
+ if (m_runningInDesigner || boundingSize.width() <= 0 || boundingSize.height() <= 0
+ || m_controller.isNull() || !window()) {
+ delete oldNode;
+ return 0;
+ }
+ DeclarativeRenderNode *node = static_cast<DeclarativeRenderNode *>(oldNode);
+
+ if (!node) {
+ node = new DeclarativeRenderNode(this, m_nodeMutex);
+ node->setController(m_controller.data());
+ node->setQuickWindow(window());
+ }
+
+ node->setSize(boundingSize);
+ node->setSamples(m_samples);
+ node->update();
+ node->markDirty(QSGNode::DirtyMaterial);
+
+ return node;
+}
+
+Declarative3DScene* AbstractDeclarative::scene() const
+{
+ return static_cast<Declarative3DScene *>(m_controller->scene());
+}
+
+void AbstractDeclarative::setTheme(Q3DTheme *theme)
+{
+ m_controller->setActiveTheme(theme, isComponentComplete());
+}
+
+Q3DTheme *AbstractDeclarative::theme() const
+{
+ return m_controller->activeTheme();
+}
+
+void AbstractDeclarative::clearSelection()
+{
+ m_controller->clearSelection();
+}
+
+void AbstractDeclarative::setSelectionMode(SelectionFlags mode)
+{
+ int intmode = int(mode);
+ m_controller->setSelectionMode(QAbstract3DGraph::SelectionFlags(intmode));
+}
+
+AbstractDeclarative::SelectionFlags AbstractDeclarative::selectionMode() const
+{
+ int intmode = int(m_controller->selectionMode());
+ return SelectionFlags(intmode);
+}
+
+void AbstractDeclarative::setShadowQuality(ShadowQuality quality)
+{
+ m_controller->setShadowQuality(QAbstract3DGraph::ShadowQuality(quality));
+}
+
+AbstractDeclarative::ShadowQuality AbstractDeclarative::shadowQuality() const
+{
+ return ShadowQuality(m_controller->shadowQuality());
+}
+
+bool AbstractDeclarative::shadowsSupported() const
+{
+ return m_controller->shadowsSupported();
+}
+
+int AbstractDeclarative::addCustomItem(QCustom3DItem *item)
+{
+ return m_controller->addCustomItem(item);
+}
+
+void AbstractDeclarative::removeCustomItems()
+{
+ m_controller->deleteCustomItems();
+}
+
+void AbstractDeclarative::removeCustomItem(QCustom3DItem *item)
+{
+ m_controller->deleteCustomItem(item);
+}
+
+void AbstractDeclarative::removeCustomItemAt(const QVector3D &position)
+{
+ m_controller->deleteCustomItem(position);
+}
+
+void AbstractDeclarative::releaseCustomItem(QCustom3DItem *item)
+{
+ m_controller->releaseCustomItem(item);
+}
+
+int AbstractDeclarative::selectedLabelIndex() const
+{
+ return m_controller->selectedLabelIndex();
+}
+
+QAbstract3DAxis *AbstractDeclarative::selectedAxis() const
+{
+ return m_controller->selectedAxis();
+}
+
+int AbstractDeclarative::selectedCustomItemIndex() const
+{
+ return m_controller->selectedCustomItemIndex();
+}
+
+QCustom3DItem *AbstractDeclarative::selectedCustomItem() const
+{
+ return m_controller->selectedCustomItem();
+}
+
+QQmlListProperty<QCustom3DItem> AbstractDeclarative::customItemList()
+{
+ return QQmlListProperty<QCustom3DItem>(this, this,
+ &AbstractDeclarative::appendCustomItemFunc,
+ &AbstractDeclarative::countCustomItemFunc,
+ &AbstractDeclarative::atCustomItemFunc,
+ &AbstractDeclarative::clearCustomItemFunc);
+}
+
+void AbstractDeclarative::appendCustomItemFunc(QQmlListProperty<QCustom3DItem> *list,
+ QCustom3DItem *item)
+{
+ AbstractDeclarative *decl = reinterpret_cast<AbstractDeclarative *>(list->data);
+ decl->addCustomItem(item);
+}
+
+qsizetype AbstractDeclarative::countCustomItemFunc(QQmlListProperty<QCustom3DItem> *list)
+{
+ return reinterpret_cast<AbstractDeclarative *>(list->data)->m_controller->m_customItems.size();
+}
+
+QCustom3DItem *AbstractDeclarative::atCustomItemFunc(QQmlListProperty<QCustom3DItem> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<AbstractDeclarative *>(list->data)->m_controller->m_customItems.at(index);
+}
+
+void AbstractDeclarative::clearCustomItemFunc(QQmlListProperty<QCustom3DItem> *list)
+{
+ AbstractDeclarative *decl = reinterpret_cast<AbstractDeclarative *>(list->data);
+ decl->removeCustomItems();
+}
+
+void AbstractDeclarative::setSharedController(Abstract3DController *controller)
+{
+ Q_ASSERT(controller);
+ m_controller = controller;
+ m_controller->m_qml = this;
+
+ if (!m_controller->isOpenGLES())
+ m_samples = 4;
+ setAntialiasing(m_samples > 0);
+
+ // Reset default theme, as the default C++ theme is Q3DTheme, not DeclarativeTheme3D.
+ DeclarativeTheme3D *defaultTheme = new DeclarativeTheme3D;
+ defaultTheme->d_ptr->setDefaultTheme(true);
+ defaultTheme->setType(Q3DTheme::ThemeQt);
+ m_controller->setActiveTheme(defaultTheme);
+
+ QObject::connect(m_controller.data(), &Abstract3DController::shadowQualityChanged, this,
+ &AbstractDeclarative::handleShadowQualityChange);
+ QObject::connect(m_controller.data(), &Abstract3DController::activeInputHandlerChanged, this,
+ &AbstractDeclarative::inputHandlerChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::activeThemeChanged, this,
+ &AbstractDeclarative::themeChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::selectionModeChanged, this,
+ &AbstractDeclarative::handleSelectionModeChange);
+ QObject::connect(m_controller.data(), &Abstract3DController::elementSelected, this,
+ &AbstractDeclarative::handleSelectedElementChange);
+
+ QObject::connect(m_controller.data(), &Abstract3DController::axisXChanged, this,
+ &AbstractDeclarative::handleAxisXChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::axisYChanged, this,
+ &AbstractDeclarative::handleAxisYChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::axisZChanged, this,
+ &AbstractDeclarative::handleAxisZChanged);
+
+ QObject::connect(m_controller.data(), &Abstract3DController::measureFpsChanged, this,
+ &AbstractDeclarative::measureFpsChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::currentFpsChanged, this,
+ &AbstractDeclarative::currentFpsChanged);
+
+ QObject::connect(m_controller.data(), &Abstract3DController::orthoProjectionChanged, this,
+ &AbstractDeclarative::orthoProjectionChanged);
+
+ QObject::connect(m_controller.data(), &Abstract3DController::aspectRatioChanged, this,
+ &AbstractDeclarative::aspectRatioChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::optimizationHintsChanged, this,
+ &AbstractDeclarative::handleOptimizationHintChange);
+ QObject::connect(m_controller.data(), &Abstract3DController::polarChanged, this,
+ &AbstractDeclarative::polarChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::radialLabelOffsetChanged, this,
+ &AbstractDeclarative::radialLabelOffsetChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::horizontalAspectRatioChanged, this,
+ &AbstractDeclarative::horizontalAspectRatioChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::reflectionChanged, this,
+ &AbstractDeclarative::reflectionChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::reflectivityChanged, this,
+ &AbstractDeclarative::reflectivityChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::localeChanged, this,
+ &AbstractDeclarative::localeChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::queriedGraphPositionChanged, this,
+ &AbstractDeclarative::queriedGraphPositionChanged);
+ QObject::connect(m_controller.data(), &Abstract3DController::marginChanged, this,
+ &AbstractDeclarative::marginChanged);
+}
+
+void AbstractDeclarative::activateOpenGLContext(QQuickWindow *window)
+{
+ // We can assume we are not in middle of AbstractDeclarative destructor when we are here,
+ // since m_context creation is always done when this function is called from
+ // synchDataToRenderer(), which blocks main thread -> no need to mutex.
+ if (!m_contextOrStateStore || !m_qtContext || m_contextWindow != window) {
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+
+ // Note: Changing graph to different window when using multithreaded renderer will break!
+
+ delete m_contextOrStateStore;
+
+ m_contextThread = QThread::currentThread();
+ m_contextWindow = window;
+ m_qtContext = currentContext;
+
+#ifdef USE_SHARED_CONTEXT
+ m_context = new QOpenGLContext();
+ m_context->setFormat(m_qtContext->format());
+ m_context->setShareContext(m_qtContext);
+ m_context->create();
+ m_context->makeCurrent(window);
+#else
+ // Shared contexts don't work properly in some platforms, so just store the
+ // context state on those
+ m_stateStore = new GLStateStore(QOpenGLContext::currentContext());
+ m_stateStore->storeGLState();
+#endif
+ m_controller->initializeOpenGL();
+
+ // Make sure context / state store gets deleted.
+ QObject::connect(m_contextThread, &QThread::finished, this,
+ &AbstractDeclarative::destroyContext, Qt::DirectConnection);
+ } else {
+#ifdef USE_SHARED_CONTEXT
+ m_context->makeCurrent(window);
+#else
+ m_stateStore->storeGLState();
+#endif
+ }
+}
+
+void AbstractDeclarative::doneOpenGLContext(QQuickWindow *window)
+{
+#ifdef USE_SHARED_CONTEXT
+ m_qtContext->makeCurrent(window);
+#else
+ Q_UNUSED(window);
+ m_stateStore->restoreGLState();
+#endif
+}
+
+void AbstractDeclarative::synchDataToRenderer()
+{
+ QQuickWindow *win = window();
+ activateOpenGLContext(win);
+ m_controller->synchDataToRenderer();
+ doneOpenGLContext(win);
+}
+
+int AbstractDeclarative::msaaSamples() const
+{
+ if (m_renderMode == RenderIndirect)
+ return m_samples;
+ else
+ return m_windowSamples;
+}
+
+void AbstractDeclarative::setMsaaSamples(int samples)
+{
+ if (m_renderMode != RenderIndirect) {
+ qWarning("Multisampling cannot be adjusted in this render mode");
+ } else {
+ if (m_controller->isOpenGLES()) {
+ if (samples > 0)
+ qWarning("Multisampling is not supported in OpenGL ES2");
+ } else if (m_samples != samples) {
+ m_samples = samples;
+ setAntialiasing(m_samples > 0);
+ emit msaaSamplesChanged(samples);
+ update();
+ }
+ }
+}
+
+void AbstractDeclarative::handleWindowChanged(QQuickWindow *window)
+{
+ checkWindowList(window);
+ if (!window)
+ return;
+
+#if defined(Q_OS_OSX)
+ bool previousVisibility = window->isVisible();
+ // Enable touch events for Mac touchpads
+ window->setVisible(true);
+ typedef void * (*EnableTouch)(QWindow*, bool);
+ EnableTouch enableTouch =
+ (EnableTouch)QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration("registertouchwindow");
+ if (enableTouch)
+ enableTouch(window, true);
+ window->setVisible(previousVisibility);
+#endif
+
+ connect(window, &QObject::destroyed, this, &AbstractDeclarative::windowDestroyed);
+
+ int oldWindowSamples = m_windowSamples;
+ m_windowSamples = window->format().samples();
+ if (m_windowSamples < 0)
+ m_windowSamples = 0;
+
+ connect(window, &QQuickWindow::beforeSynchronizing,
+ this, &AbstractDeclarative::synchDataToRenderer,
+ Qt::DirectConnection);
+
+ if (m_renderMode == RenderDirectToBackground_NoClear
+ || m_renderMode == RenderDirectToBackground) {
+ connect(window, &QQuickWindow::beforeRenderPassRecording, this, &AbstractDeclarative::render,
+ Qt::DirectConnection);
+ setAntialiasing(m_windowSamples > 0);
+ if (m_windowSamples != oldWindowSamples)
+ emit msaaSamplesChanged(m_windowSamples);
+ }
+
+ connect(m_controller.data(), &Abstract3DController::needRender, window, &QQuickWindow::update);
+
+ updateWindowParameters();
+
+#if defined(Q_OS_IOS)
+ // Scenegraph render cycle in iOS sometimes misses update after beforeSynchronizing signal.
+ // This ensures we don't end up displaying the graph without any data, in case update is
+ // skipped after synchDataToRenderer.
+ QTimer::singleShot(0, window, SLOT(update()));
+#endif
+}
+
+void AbstractDeclarative::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
+
+ m_cachedGeometry = newGeometry;
+
+ updateWindowParameters();
+}
+
+void AbstractDeclarative::itemChange(ItemChange change, const ItemChangeData & value)
+{
+ QQuickItem::itemChange(change, value);
+ updateWindowParameters();
+}
+
+void AbstractDeclarative::updateWindowParameters()
+{
+ const QMutexLocker locker(&m_mutex);
+
+ // Update the device pixel ratio, window size and bounding box
+ QQuickWindow *win = window();
+ if (win && !m_controller.isNull()) {
+ Q3DScene *scene = m_controller->scene();
+ if (win->devicePixelRatio() != scene->devicePixelRatio()) {
+ scene->setDevicePixelRatio(win->devicePixelRatio());
+ win->update();
+ }
+
+ bool directRender = m_renderMode == RenderDirectToBackground
+ || m_renderMode == RenderDirectToBackground_NoClear;
+ QSize windowSize;
+
+ if (directRender)
+ windowSize = win->size();
+ else
+ windowSize = m_cachedGeometry.size().toSize();
+
+ if (windowSize != scene->d_ptr->windowSize()) {
+ scene->d_ptr->setWindowSize(windowSize);
+ win->update();
+ }
+
+ if (directRender) {
+ // Origin mapping is needed when rendering directly to background
+ QPointF point = QQuickItem::mapToScene(QPointF(0.0, 0.0));
+ scene->d_ptr->setViewport(QRect(point.x() + 0.5f, point.y() + 0.5f,
+ m_cachedGeometry.width() + 0.5f,
+ m_cachedGeometry.height() + 0.5f));
+ } else {
+ // No translation needed when rendering to FBO
+ scene->d_ptr->setViewport(QRect(0.0, 0.0, m_cachedGeometry.width() + 0.5f,
+ m_cachedGeometry.height() + 0.5f));
+ }
+ }
+}
+
+void AbstractDeclarative::handleSelectionModeChange(QAbstract3DGraph::SelectionFlags mode)
+{
+ int intmode = int(mode);
+ emit selectionModeChanged(SelectionFlags(intmode));
+}
+
+void AbstractDeclarative::handleShadowQualityChange(QAbstract3DGraph::ShadowQuality quality)
+{
+ emit shadowQualityChanged(ShadowQuality(quality));
+}
+
+void AbstractDeclarative::handleSelectedElementChange(QAbstract3DGraph::ElementType type)
+{
+ emit selectedElementChanged(ElementType(type));
+}
+
+void AbstractDeclarative::handleOptimizationHintChange(QAbstract3DGraph::OptimizationHints hints)
+{
+ int intHints = int(hints);
+ emit optimizationHintsChanged(OptimizationHints(intHints));
+}
+
+void AbstractDeclarative::render()
+{
+ updateWindowParameters();
+
+ // If we're not rendering directly to the background, return
+ if (m_renderMode != RenderDirectToBackground && m_renderMode != RenderDirectToBackground_NoClear)
+ return;
+
+ // Clear the background once per window as that is not done by default
+ QQuickWindow *win = window();
+ win->beginExternalCommands();
+ activateOpenGLContext(win);
+
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+
+ if (isVisible()) {
+ funcs->glDepthMask(GL_TRUE);
+ funcs->glEnable(GL_DEPTH_TEST);
+ funcs->glDepthFunc(GL_LESS);
+ funcs->glEnable(GL_CULL_FACE);
+ funcs->glCullFace(GL_BACK);
+ funcs->glDisable(GL_BLEND);
+
+ m_controller->render();
+
+ funcs->glEnable(GL_BLEND);
+ }
+
+ doneOpenGLContext(win);
+ win->endExternalCommands();
+}
+
+QAbstract3DInputHandler* AbstractDeclarative::inputHandler() const
+{
+ return m_controller->activeInputHandler();
+}
+
+void AbstractDeclarative::setInputHandler(QAbstract3DInputHandler *inputHandler)
+{
+ m_controller->setActiveInputHandler(inputHandler);
+}
+
+void AbstractDeclarative::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ m_controller->mouseDoubleClickEvent(event);
+}
+
+void AbstractDeclarative::touchEvent(QTouchEvent *event)
+{
+ m_controller->touchEvent(event);
+ window()->update();
+}
+
+void AbstractDeclarative::mousePressEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ m_controller->mousePressEvent(event, mousePos);
+}
+
+void AbstractDeclarative::mouseReleaseEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ m_controller->mouseReleaseEvent(event, mousePos);
+}
+
+void AbstractDeclarative::mouseMoveEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ m_controller->mouseMoveEvent(event, mousePos);
+}
+
+#if QT_CONFIG(wheelevent)
+void AbstractDeclarative::wheelEvent(QWheelEvent *event)
+{
+ m_controller->wheelEvent(event);
+}
+#endif
+
+void AbstractDeclarative::checkWindowList(QQuickWindow *window)
+{
+ QQuickWindow *oldWindow = graphWindowList.value(this);
+ graphWindowList[this] = window;
+
+ if (oldWindow != window && oldWindow) {
+ QObject::disconnect(oldWindow, &QObject::destroyed, this,
+ &AbstractDeclarative::windowDestroyed);
+ QObject::disconnect(oldWindow, &QQuickWindow::beforeSynchronizing, this,
+ &AbstractDeclarative::synchDataToRenderer);
+ QObject::disconnect(oldWindow, &QQuickWindow::beforeRenderPassRecording, this,
+ &AbstractDeclarative::render);
+ if (!m_controller.isNull()) {
+ QObject::disconnect(m_controller.data(), &Abstract3DController::needRender,
+ oldWindow, &QQuickWindow::update);
+ }
+ }
+
+ QList<QQuickWindow *> windowList;
+
+ foreach (AbstractDeclarative *graph, graphWindowList.keys()) {
+ if (graph->m_renderMode == RenderDirectToBackground
+ || graph->m_renderMode == RenderDirectToBackground_NoClear) {
+ windowList.append(graphWindowList.value(graph));
+ }
+ }
+
+ if (!window) {
+ graphWindowList.remove(this);
+ return;
+ }
+}
+
+void AbstractDeclarative::setMeasureFps(bool enable)
+{
+ m_controller->setMeasureFps(enable);
+}
+
+bool AbstractDeclarative::measureFps() const
+{
+ return m_controller->measureFps();
+}
+
+qreal AbstractDeclarative::currentFps() const
+{
+ return m_controller->currentFps();
+}
+
+void AbstractDeclarative::setOrthoProjection(bool enable)
+{
+ m_controller->setOrthoProjection(enable);
+}
+
+bool AbstractDeclarative::isOrthoProjection() const
+{
+ return m_controller->isOrthoProjection();
+}
+
+AbstractDeclarative::ElementType AbstractDeclarative::selectedElement() const
+{
+ return ElementType(m_controller->selectedElement());
+}
+
+void AbstractDeclarative::setAspectRatio(qreal ratio)
+{
+ m_controller->setAspectRatio(ratio);
+}
+
+qreal AbstractDeclarative::aspectRatio() const
+{
+ return m_controller->aspectRatio();
+}
+
+void AbstractDeclarative::setOptimizationHints(OptimizationHints hints)
+{
+ int intmode = int(hints);
+ m_controller->setOptimizationHints(QAbstract3DGraph::OptimizationHints(intmode));
+}
+
+AbstractDeclarative::OptimizationHints AbstractDeclarative::optimizationHints() const
+{
+ int intmode = int(m_controller->optimizationHints());
+ return OptimizationHints(intmode);
+}
+
+void AbstractDeclarative::setPolar(bool enable)
+{
+ m_controller->setPolar(enable);
+}
+
+bool AbstractDeclarative::isPolar() const
+{
+ return m_controller->isPolar();
+}
+
+void AbstractDeclarative::setRadialLabelOffset(float offset)
+{
+ m_controller->setRadialLabelOffset(offset);
+}
+
+float AbstractDeclarative::radialLabelOffset() const
+{
+ return m_controller->radialLabelOffset();
+}
+
+void AbstractDeclarative::setHorizontalAspectRatio(qreal ratio)
+{
+ m_controller->setHorizontalAspectRatio(ratio);
+}
+
+qreal AbstractDeclarative::horizontalAspectRatio() const
+{
+ return m_controller->horizontalAspectRatio();
+}
+
+void AbstractDeclarative::setReflection(bool enable)
+{
+ m_controller->setReflection(enable);
+}
+
+bool AbstractDeclarative::isReflection() const
+{
+ return m_controller->reflection();
+}
+
+void AbstractDeclarative::setReflectivity(qreal reflectivity)
+{
+ m_controller->setReflectivity(reflectivity);
+}
+
+qreal AbstractDeclarative::reflectivity() const
+{
+ return m_controller->reflectivity();
+}
+
+void AbstractDeclarative::setLocale(const QLocale &locale)
+{
+ m_controller->setLocale(locale);
+}
+
+QLocale AbstractDeclarative::locale() const
+{
+ return m_controller->locale();
+}
+
+QVector3D AbstractDeclarative::queriedGraphPosition() const
+{
+ return m_controller->queriedGraphPosition();
+}
+
+void AbstractDeclarative::setMargin(qreal margin)
+{
+ m_controller->setMargin(margin);
+}
+
+qreal AbstractDeclarative::margin() const
+{
+ return m_controller->margin();
+}
+
+void AbstractDeclarative::windowDestroyed(QObject *obj)
+{
+ // Remove destroyed window from window lists
+ QQuickWindow *win = static_cast<QQuickWindow *>(obj);
+ QQuickWindow *oldWindow = graphWindowList.value(this);
+
+ if (win == oldWindow)
+ graphWindowList.remove(this);
+}
+
+void AbstractDeclarative::destroyContext()
+{
+ if (m_contextThread && m_contextThread != m_mainThread) {
+ if (m_contextOrStateStore)
+ m_contextOrStateStore->deleteLater();
+ } else {
+ delete m_contextOrStateStore;
+ }
+ m_contextOrStateStore = 0;
+
+ if (m_contextThread) {
+ QObject::disconnect(m_contextThread, &QThread::finished, this,
+ &AbstractDeclarative::destroyContext);
+ m_contextThread = 0;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/abstractdeclarative_p.h b/src/datavisualizationqml/abstractdeclarative_p.h
new file mode 100644
index 00000000..3b9d4d96
--- /dev/null
+++ b/src/datavisualizationqml/abstractdeclarative_p.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef ABSTRACTDECLARATIVE_P_H
+#define ABSTRACTDECLARATIVE_P_H
+
+#include "declarativescene_p.h"
+
+#include <private/datavisualizationglobal_p.h>
+#include <private/abstract3dcontroller_p.h>
+
+#include <QtQuick/QQuickItem>
+#include <QtCore/QPointer>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtCore/QSharedPointer>
+
+class GLStateStore;
+
+QT_BEGIN_NAMESPACE
+
+class AbstractDeclarative : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged)
+ Q_PROPERTY(ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged)
+ Q_PROPERTY(bool shadowsSupported READ shadowsSupported NOTIFY shadowsSupportedChanged)
+ Q_PROPERTY(int msaaSamples READ msaaSamples WRITE setMsaaSamples NOTIFY msaaSamplesChanged)
+ Q_PROPERTY(Declarative3DScene* scene READ scene NOTIFY sceneChanged)
+ Q_PROPERTY(QAbstract3DInputHandler* inputHandler READ inputHandler WRITE setInputHandler NOTIFY inputHandlerChanged)
+ Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged)
+ Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode NOTIFY renderingModeChanged)
+ Q_PROPERTY(bool measureFps READ measureFps WRITE setMeasureFps NOTIFY measureFpsChanged REVISION(1, 1))
+ Q_PROPERTY(qreal currentFps READ currentFps NOTIFY currentFpsChanged REVISION(1, 1))
+ Q_PROPERTY(QQmlListProperty<QCustom3DItem> customItemList READ customItemList REVISION(1, 1))
+ Q_PROPERTY(bool orthoProjection READ isOrthoProjection WRITE setOrthoProjection NOTIFY orthoProjectionChanged REVISION(1, 1))
+ Q_PROPERTY(ElementType selectedElement READ selectedElement NOTIFY selectedElementChanged REVISION(1, 1))
+ Q_PROPERTY(qreal aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged REVISION(1, 1))
+ Q_PROPERTY(OptimizationHints optimizationHints READ optimizationHints WRITE setOptimizationHints NOTIFY optimizationHintsChanged REVISION(1, 1))
+ Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged REVISION(1, 2))
+ Q_PROPERTY(float radialLabelOffset READ radialLabelOffset WRITE setRadialLabelOffset NOTIFY radialLabelOffsetChanged REVISION(1, 2))
+ Q_PROPERTY(qreal horizontalAspectRatio READ horizontalAspectRatio WRITE setHorizontalAspectRatio NOTIFY horizontalAspectRatioChanged REVISION(1, 2))
+ Q_PROPERTY(bool reflection READ isReflection WRITE setReflection NOTIFY reflectionChanged REVISION(1, 2))
+ Q_PROPERTY(qreal reflectivity READ reflectivity WRITE setReflectivity NOTIFY reflectivityChanged REVISION(1, 2))
+ Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged REVISION(1, 2))
+ Q_PROPERTY(QVector3D queriedGraphPosition READ queriedGraphPosition NOTIFY queriedGraphPositionChanged REVISION(1, 2))
+ Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged REVISION(1, 2))
+
+ QML_NAMED_ELEMENT(AbstractGraph3D)
+ QML_ADDED_IN_VERSION(1, 0)
+ QML_UNCREATABLE("Trying to create uncreatable: AbstractGraph3D.")
+
+public:
+ enum SelectionFlag {
+ SelectionNone = 0,
+ SelectionItem = 1,
+ SelectionRow = 2,
+ SelectionItemAndRow = SelectionItem | SelectionRow,
+ SelectionColumn = 4,
+ SelectionItemAndColumn = SelectionItem | SelectionColumn,
+ SelectionRowAndColumn = SelectionRow | SelectionColumn,
+ SelectionItemRowAndColumn = SelectionItem | SelectionRow | SelectionColumn,
+ SelectionSlice = 8,
+ SelectionMultiSeries = 16
+ };
+ Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
+
+ enum ShadowQuality {
+ ShadowQualityNone = 0,
+ ShadowQualityLow,
+ ShadowQualityMedium,
+ ShadowQualityHigh,
+ ShadowQualitySoftLow,
+ ShadowQualitySoftMedium,
+ ShadowQualitySoftHigh
+ };
+
+ enum ElementType {
+ ElementNone = 0,
+ ElementSeries,
+ ElementAxisXLabel,
+ ElementAxisYLabel,
+ ElementAxisZLabel,
+ ElementCustomItem
+ };
+
+ enum RenderingMode {
+ RenderDirectToBackground = 0,
+ RenderDirectToBackground_NoClear,
+ RenderIndirect
+ };
+
+ enum OptimizationHint {
+ OptimizationDefault = 0,
+ OptimizationStatic = 1
+ };
+ Q_DECLARE_FLAGS(OptimizationHints, OptimizationHint)
+
+ Q_ENUM(ShadowQuality)
+ Q_ENUM(RenderingMode)
+ Q_ENUM(ElementType)
+ Q_FLAGS(SelectionFlag SelectionFlags)
+ Q_FLAGS(OptimizationHint OptimizationHints)
+
+public:
+ explicit AbstractDeclarative(QQuickItem *parent = 0);
+ virtual ~AbstractDeclarative();
+
+ virtual void setRenderingMode(RenderingMode mode);
+ virtual AbstractDeclarative::RenderingMode renderingMode() const;
+
+ virtual void setSelectionMode(SelectionFlags mode);
+ virtual AbstractDeclarative::SelectionFlags selectionMode() const;
+
+ virtual void setShadowQuality(ShadowQuality quality);
+ virtual AbstractDeclarative::ShadowQuality shadowQuality() const;
+
+ virtual AbstractDeclarative::ElementType selectedElement() const;
+
+ virtual bool shadowsSupported() const;
+
+ virtual void setMsaaSamples(int samples);
+ virtual int msaaSamples() const;
+
+ virtual Declarative3DScene *scene() const;
+
+ virtual QAbstract3DInputHandler *inputHandler() const;
+ virtual void setInputHandler(QAbstract3DInputHandler *inputHandler);
+
+ virtual void setTheme(Q3DTheme *theme);
+ virtual Q3DTheme *theme() const;
+
+ Q_INVOKABLE virtual void clearSelection();
+
+ Q_REVISION(1, 1) Q_INVOKABLE virtual int addCustomItem(QCustom3DItem *item);
+ Q_REVISION(1, 1) Q_INVOKABLE virtual void removeCustomItems();
+ Q_REVISION(1, 1) Q_INVOKABLE virtual void removeCustomItem(QCustom3DItem *item);
+ Q_REVISION(1, 1) Q_INVOKABLE virtual void removeCustomItemAt(const QVector3D &position);
+ Q_REVISION(1, 1) Q_INVOKABLE virtual void releaseCustomItem(QCustom3DItem *item);
+
+ Q_REVISION(1, 1) Q_INVOKABLE virtual int selectedLabelIndex() const;
+ Q_REVISION(1, 1) Q_INVOKABLE virtual QAbstract3DAxis *selectedAxis() const;
+
+ Q_REVISION(1, 1) Q_INVOKABLE virtual int selectedCustomItemIndex() const;
+ Q_REVISION(1, 1) Q_INVOKABLE virtual QCustom3DItem *selectedCustomItem() const;
+
+ QQmlListProperty<QCustom3DItem> customItemList();
+ static void appendCustomItemFunc(QQmlListProperty<QCustom3DItem> *list,
+ QCustom3DItem *item);
+ static qsizetype countCustomItemFunc(QQmlListProperty<QCustom3DItem> *list);
+ static QCustom3DItem *atCustomItemFunc(QQmlListProperty<QCustom3DItem> *list, qsizetype index);
+ static void clearCustomItemFunc(QQmlListProperty<QCustom3DItem> *list);
+
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
+ void setSharedController(Abstract3DController *controller);
+ // Used to synch up data model from controller to renderer while main thread is locked
+ void synchDataToRenderer();
+ void render();
+
+ void activateOpenGLContext(QQuickWindow *window);
+ void doneOpenGLContext(QQuickWindow *window);
+
+ void checkWindowList(QQuickWindow *window);
+
+ void setMeasureFps(bool enable);
+ bool measureFps() const;
+ qreal currentFps() const;
+
+ void setOrthoProjection(bool enable);
+ bool isOrthoProjection() const;
+
+ void setAspectRatio(qreal ratio);
+ qreal aspectRatio() const;
+
+ void setOptimizationHints(OptimizationHints hints);
+ OptimizationHints optimizationHints() const;
+
+ void setPolar(bool enable);
+ bool isPolar() const;
+
+ void setRadialLabelOffset(float offset);
+ float radialLabelOffset() const;
+
+ void setHorizontalAspectRatio(qreal ratio);
+ qreal horizontalAspectRatio() const;
+
+ void setReflection(bool enable);
+ bool isReflection() const;
+
+ void setReflectivity(qreal reflectivity);
+ qreal reflectivity() const;
+
+ void setLocale(const QLocale &locale);
+ QLocale locale() const;
+
+ QVector3D queriedGraphPosition() const;
+
+ void setMargin(qreal margin);
+ qreal margin() const;
+
+ QMutex *mutex() { return &m_mutex; }
+
+ bool isReady() { return isComponentComplete(); }
+
+public Q_SLOTS:
+ virtual void handleAxisXChanged(QAbstract3DAxis *axis) = 0;
+ virtual void handleAxisYChanged(QAbstract3DAxis *axis) = 0;
+ virtual void handleAxisZChanged(QAbstract3DAxis *axis) = 0;
+ void windowDestroyed(QObject *obj);
+ void destroyContext();
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void touchEvent(QTouchEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+#if QT_CONFIG(wheelevent)
+ void wheelEvent(QWheelEvent *event) override;
+#endif
+ virtual void handleWindowChanged(QQuickWindow *win);
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
+ virtual void updateWindowParameters();
+ virtual void handleSelectionModeChange(QAbstract3DGraph::SelectionFlags mode);
+ virtual void handleShadowQualityChange(QAbstract3DGraph::ShadowQuality quality);
+ virtual void handleSelectedElementChange(QAbstract3DGraph::ElementType type);
+ virtual void handleOptimizationHintChange(QAbstract3DGraph::OptimizationHints hints);
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
+
+Q_SIGNALS:
+ void selectionModeChanged(AbstractDeclarative::SelectionFlags mode);
+ void shadowQualityChanged(AbstractDeclarative::ShadowQuality quality);
+ void shadowsSupportedChanged(bool supported);
+ void msaaSamplesChanged(int samples);
+ void sceneChanged(Q3DScene *scene);
+ void inputHandlerChanged(QAbstract3DInputHandler *inputHandler);
+ void themeChanged(Q3DTheme *theme);
+ void renderingModeChanged(AbstractDeclarative::RenderingMode mode);
+ Q_REVISION(1, 1) void measureFpsChanged(bool enabled);
+ Q_REVISION(1, 1) void currentFpsChanged(qreal fps);
+ Q_REVISION(1, 1) void selectedElementChanged(AbstractDeclarative::ElementType type);
+ Q_REVISION(1, 1) void orthoProjectionChanged(bool enabled);
+ Q_REVISION(1, 1) void aspectRatioChanged(qreal ratio);
+ Q_REVISION(1, 1) void optimizationHintsChanged(AbstractDeclarative::OptimizationHints hints);
+ Q_REVISION(1, 2) void polarChanged(bool enabled);
+ Q_REVISION(1, 2) void radialLabelOffsetChanged(float offset);
+ Q_REVISION(1, 2) void horizontalAspectRatioChanged(qreal ratio);
+ Q_REVISION(1, 2) void reflectionChanged(bool enabled);
+ Q_REVISION(1, 2) void reflectivityChanged(qreal reflectivity);
+ Q_REVISION(1, 2) void localeChanged(const QLocale &locale);
+ Q_REVISION(1, 2) void queriedGraphPositionChanged(const QVector3D &data);
+ Q_REVISION(1, 2) void marginChanged(qreal margin);
+
+protected:
+ QSharedPointer<QMutex> m_nodeMutex;
+
+private:
+ QPointer<Abstract3DController> m_controller;
+ QRectF m_cachedGeometry;
+ QPointer<QQuickWindow> m_contextWindow;
+ AbstractDeclarative::RenderingMode m_renderMode;
+ int m_samples;
+ int m_windowSamples;
+ QSize m_initialisedSize;
+ union {
+ QObject *m_contextOrStateStore;
+ QOpenGLContext *m_context;
+ GLStateStore *m_stateStore;
+ };
+ QPointer<QOpenGLContext> m_qtContext;
+ QThread *m_mainThread;
+ QThread *m_contextThread;
+ bool m_runningInDesigner;
+ QMutex m_mutex;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractDeclarative::SelectionFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractDeclarative::OptimizationHints)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/colorgradient.cpp b/src/datavisualizationqml/colorgradient.cpp
new file mode 100644
index 00000000..3f6881b0
--- /dev/null
+++ b/src/datavisualizationqml/colorgradient.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "colorgradient_p.h"
+
+QT_BEGIN_NAMESPACE
+
+ColorGradientStop::ColorGradientStop(QObject *parent)
+ : QObject(parent)
+{
+}
+
+qreal ColorGradientStop::position() const
+{
+ return m_position;
+}
+
+void ColorGradientStop::setPosition(qreal position)
+{
+ m_position = position;
+ updateGradient();
+ emit positionChanged(position);
+}
+
+QColor ColorGradientStop::color() const
+{
+ return m_color;
+}
+
+void ColorGradientStop::setColor(const QColor &color)
+{
+ m_color = color;
+ updateGradient();
+ emit colorChanged(color);
+}
+
+void ColorGradientStop::updateGradient()
+{
+ if (ColorGradient *grad = qobject_cast<ColorGradient*>(parent()))
+ grad->doUpdate();
+}
+
+ColorGradient::ColorGradient(QObject *parent)
+: QObject(parent)
+{
+}
+
+ColorGradient::~ColorGradient()
+{
+}
+
+QQmlListProperty<ColorGradientStop> ColorGradient::stops()
+{
+ return QQmlListProperty<ColorGradientStop>(this, &m_stops);
+}
+
+void ColorGradient::doUpdate()
+{
+ emit updated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/colorgradient_p.h b/src/datavisualizationqml/colorgradient_p.h
new file mode 100644
index 00000000..ec21cd2f
--- /dev/null
+++ b/src/datavisualizationqml/colorgradient_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef COLORGRADIENT_P_H
+#define COLORGRADIENT_P_H
+
+#include <private/datavisualizationglobal_p.h>
+#include <QtGui/QColor>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class ColorGradientStop : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+
+ QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ ColorGradientStop(QObject *parent = 0);
+
+ qreal position() const;
+ void setPosition(qreal position);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+Q_SIGNALS:
+ void positionChanged(qreal position);
+ void colorChanged(QColor color);
+
+private:
+ void updateGradient();
+
+private:
+ qreal m_position;
+ QColor m_color;
+};
+
+class ColorGradient : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQmlListProperty<ColorGradientStop> stops READ stops)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+ QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ ColorGradient(QObject *parent = 0);
+ ~ColorGradient();
+
+ QQmlListProperty<ColorGradientStop> stops();
+
+ void doUpdate();
+ QList<ColorGradientStop *> m_stops;
+
+Q_SIGNALS:
+ void updated();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativebars.cpp b/src/datavisualizationqml/declarativebars.cpp
new file mode 100644
index 00000000..fe90e159
--- /dev/null
+++ b/src/datavisualizationqml/declarativebars.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativebars_p.h"
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeBars::DeclarativeBars(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_barsController(0)
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // Create the shared component on the main GUI thread.
+ m_barsController = new Bars3DController(boundingRect().toRect(), new Declarative3DScene);
+ AbstractDeclarative::setSharedController(m_barsController);
+
+ QObject::connect(m_barsController, &Bars3DController::primarySeriesChanged,
+ this, &DeclarativeBars::primarySeriesChanged);
+ QObject::connect(m_barsController, &Bars3DController::selectedSeriesChanged,
+ this, &DeclarativeBars::selectedSeriesChanged);
+}
+
+DeclarativeBars::~DeclarativeBars()
+{
+ QMutexLocker locker(m_nodeMutex.data());
+ const QMutexLocker locker2(mutex());
+ delete m_barsController;
+}
+
+QCategory3DAxis *DeclarativeBars::rowAxis() const
+{
+ return static_cast<QCategory3DAxis *>(m_barsController->axisZ());
+}
+
+void DeclarativeBars::setRowAxis(QCategory3DAxis *axis)
+{
+ m_barsController->setAxisZ(axis);
+}
+
+QValue3DAxis *DeclarativeBars::valueAxis() const
+{
+ return static_cast<QValue3DAxis *>(m_barsController->axisY());
+}
+
+void DeclarativeBars::setValueAxis(QValue3DAxis *axis)
+{
+ m_barsController->setAxisY(axis);
+}
+
+QCategory3DAxis *DeclarativeBars::columnAxis() const
+{
+ return static_cast<QCategory3DAxis *>(m_barsController->axisX());
+}
+
+void DeclarativeBars::setColumnAxis(QCategory3DAxis *axis)
+{
+ m_barsController->setAxisX(axis);
+}
+
+void DeclarativeBars::setMultiSeriesUniform(bool uniform)
+{
+ if (uniform != isMultiSeriesUniform()) {
+ m_barsController->setMultiSeriesScaling(uniform);
+ emit multiSeriesUniformChanged(uniform);
+ }
+}
+
+bool DeclarativeBars::isMultiSeriesUniform() const
+{
+ return m_barsController->multiSeriesScaling();
+}
+
+void DeclarativeBars::setBarThickness(float thicknessRatio)
+{
+ if (thicknessRatio != barThickness()) {
+ m_barsController->setBarSpecs(GLfloat(thicknessRatio), barSpacing(),
+ isBarSpacingRelative());
+ emit barThicknessChanged(thicknessRatio);
+ }
+}
+
+float DeclarativeBars::barThickness() const
+{
+ return m_barsController->barThickness();
+}
+
+void DeclarativeBars::setBarSpacing(QSizeF spacing)
+{
+ if (spacing != barSpacing()) {
+ m_barsController->setBarSpecs(GLfloat(barThickness()), spacing, isBarSpacingRelative());
+ emit barSpacingChanged(spacing);
+ }
+}
+
+QSizeF DeclarativeBars::barSpacing() const
+{
+ return m_barsController->barSpacing();
+}
+
+void DeclarativeBars::setBarSpacingRelative(bool relative)
+{
+ if (relative != isBarSpacingRelative()) {
+ m_barsController->setBarSpecs(GLfloat(barThickness()), barSpacing(), relative);
+ emit barSpacingRelativeChanged(relative);
+ }
+}
+
+bool DeclarativeBars::isBarSpacingRelative() const
+{
+ return m_barsController->isBarSpecRelative();
+}
+
+QBar3DSeries *DeclarativeBars::selectedSeries() const
+{
+ return m_barsController->selectedSeries();
+}
+
+void DeclarativeBars::setFloorLevel(float level)
+{
+ if (level != floorLevel()) {
+ m_barsController->setFloorLevel(level);
+ emit floorLevelChanged(level);
+ }
+}
+
+float DeclarativeBars::floorLevel() const
+{
+ return m_barsController->floorLevel();
+}
+
+QQmlListProperty<QBar3DSeries> DeclarativeBars::seriesList()
+{
+ return QQmlListProperty<QBar3DSeries>(this, this,
+ &DeclarativeBars::appendSeriesFunc,
+ &DeclarativeBars::countSeriesFunc,
+ &DeclarativeBars::atSeriesFunc,
+ &DeclarativeBars::clearSeriesFunc);
+}
+
+void DeclarativeBars::appendSeriesFunc(QQmlListProperty<QBar3DSeries> *list, QBar3DSeries *series)
+{
+ reinterpret_cast<DeclarativeBars *>(list->data)->addSeries(series);
+}
+
+qsizetype DeclarativeBars::countSeriesFunc(QQmlListProperty<QBar3DSeries> *list)
+{
+ return reinterpret_cast<DeclarativeBars *>(list->data)->m_barsController->barSeriesList().size();
+}
+
+QBar3DSeries *DeclarativeBars::atSeriesFunc(QQmlListProperty<QBar3DSeries> *list, qsizetype index)
+{
+ return reinterpret_cast<DeclarativeBars *>(list->data)->m_barsController->barSeriesList().at(index);
+}
+
+void DeclarativeBars::clearSeriesFunc(QQmlListProperty<QBar3DSeries> *list)
+{
+ DeclarativeBars *declBars = reinterpret_cast<DeclarativeBars *>(list->data);
+ QList<QBar3DSeries *> realList = declBars->m_barsController->barSeriesList();
+ int count = realList.size();
+ for (int i = 0; i < count; i++)
+ declBars->removeSeries(realList.at(i));
+}
+
+void DeclarativeBars::addSeries(QBar3DSeries *series)
+{
+ m_barsController->addSeries(series);
+}
+
+void DeclarativeBars::removeSeries(QBar3DSeries *series)
+{
+ m_barsController->removeSeries(series);
+ series->setParent(this); // Reparent as removing will leave series parentless
+}
+
+void DeclarativeBars::insertSeries(int index, QBar3DSeries *series)
+{
+ m_barsController->insertSeries(index, series);
+}
+
+void DeclarativeBars::setPrimarySeries(QBar3DSeries *series)
+{
+ m_barsController->setPrimarySeries(series);
+}
+
+QBar3DSeries *DeclarativeBars::primarySeries() const
+{
+ return m_barsController->primarySeries();
+}
+
+void DeclarativeBars::handleAxisXChanged(QAbstract3DAxis *axis)
+{
+ emit columnAxisChanged(static_cast<QCategory3DAxis *>(axis));
+}
+
+void DeclarativeBars::handleAxisYChanged(QAbstract3DAxis *axis)
+{
+ emit valueAxisChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+void DeclarativeBars::handleAxisZChanged(QAbstract3DAxis *axis)
+{
+ emit rowAxisChanged(static_cast<QCategory3DAxis *>(axis));
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativebars_p.h b/src/datavisualizationqml/declarativebars_p.h
new file mode 100644
index 00000000..acf1a030
--- /dev/null
+++ b/src/datavisualizationqml/declarativebars_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVEBARS_P_H
+#define DECLARATIVEBARS_P_H
+
+#include "abstractdeclarative_p.h"
+
+#include <private/datavisualizationglobal_p.h>
+#include <private/bars3dcontroller_p.h>
+
+QT_BEGIN_NAMESPACE
+class DeclarativeBars : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QCategory3DAxis *rowAxis READ rowAxis WRITE setRowAxis NOTIFY rowAxisChanged)
+ Q_PROPERTY(QValue3DAxis *valueAxis READ valueAxis WRITE setValueAxis NOTIFY valueAxisChanged)
+ Q_PROPERTY(QCategory3DAxis *columnAxis READ columnAxis WRITE setColumnAxis NOTIFY columnAxisChanged)
+ Q_PROPERTY(bool multiSeriesUniform READ isMultiSeriesUniform WRITE setMultiSeriesUniform NOTIFY multiSeriesUniformChanged)
+ Q_PROPERTY(float barThickness READ barThickness WRITE setBarThickness NOTIFY barThicknessChanged)
+ Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing NOTIFY barSpacingChanged)
+ Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative NOTIFY barSpacingRelativeChanged)
+ Q_PROPERTY(QQmlListProperty<QBar3DSeries> seriesList READ seriesList)
+ Q_PROPERTY(QBar3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
+ Q_PROPERTY(QBar3DSeries *primarySeries READ primarySeries WRITE setPrimarySeries NOTIFY primarySeriesChanged)
+ Q_PROPERTY(float floorLevel READ floorLevel WRITE setFloorLevel NOTIFY floorLevelChanged REVISION(1, 2))
+ Q_CLASSINFO("DefaultProperty", "seriesList")
+
+ QML_NAMED_ELEMENT(Bars3D)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ explicit DeclarativeBars(QQuickItem *parent = 0);
+ ~DeclarativeBars();
+
+ QCategory3DAxis *rowAxis() const;
+ void setRowAxis(QCategory3DAxis *axis);
+ QValue3DAxis *valueAxis() const;
+ void setValueAxis(QValue3DAxis *axis);
+ QCategory3DAxis *columnAxis() const;
+ void setColumnAxis(QCategory3DAxis *axis);
+
+ void setMultiSeriesUniform(bool uniform);
+ bool isMultiSeriesUniform() const;
+
+ void setBarThickness(float thicknessRatio);
+ float barThickness() const;
+
+ void setBarSpacing(QSizeF spacing);
+ QSizeF barSpacing() const;
+
+ void setBarSpacingRelative(bool relative);
+ bool isBarSpacingRelative() const;
+
+ QQmlListProperty<QBar3DSeries> seriesList();
+ static void appendSeriesFunc(QQmlListProperty<QBar3DSeries> *list, QBar3DSeries *series);
+ static qsizetype countSeriesFunc(QQmlListProperty<QBar3DSeries> *list);
+ static QBar3DSeries *atSeriesFunc(QQmlListProperty<QBar3DSeries> *list, qsizetype index);
+ static void clearSeriesFunc(QQmlListProperty<QBar3DSeries> *list);
+ Q_INVOKABLE void addSeries(QBar3DSeries *series);
+ Q_INVOKABLE void removeSeries(QBar3DSeries *series);
+ Q_INVOKABLE void insertSeries(int index, QBar3DSeries *series);
+ void setPrimarySeries(QBar3DSeries *series);
+ QBar3DSeries *primarySeries() const;
+ QBar3DSeries *selectedSeries() const;
+
+ void setFloorLevel(float level);
+ float floorLevel() const;
+
+public Q_SLOTS:
+ void handleAxisXChanged(QAbstract3DAxis *axis) override;
+ void handleAxisYChanged(QAbstract3DAxis *axis) override;
+ void handleAxisZChanged(QAbstract3DAxis *axis) override;
+
+Q_SIGNALS:
+ void rowAxisChanged(QCategory3DAxis *axis);
+ void valueAxisChanged(QValue3DAxis *axis);
+ void columnAxisChanged(QCategory3DAxis *axis);
+ void multiSeriesUniformChanged(bool uniform);
+ void barThicknessChanged(float thicknessRatio);
+ void barSpacingChanged(QSizeF spacing);
+ void barSpacingRelativeChanged(bool relative);
+ void meshFileNameChanged(QString filename);
+ void primarySeriesChanged(QBar3DSeries *series);
+ void selectedSeriesChanged(QBar3DSeries *series);
+ Q_REVISION(1, 2) void floorLevelChanged(float level);
+
+private:
+ Bars3DController *m_barsController;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativecolor.cpp b/src/datavisualizationqml/declarativecolor.cpp
new file mode 100644
index 00000000..177c0fbe
--- /dev/null
+++ b/src/datavisualizationqml/declarativecolor.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativecolor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeColor::DeclarativeColor(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void DeclarativeColor::setColor(const QColor &color)
+{
+ if (m_color != color) {
+ m_color = color;
+ emit colorChanged(color);
+ }
+}
+
+QColor DeclarativeColor::color() const
+{
+ return m_color;
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativecolor_p.h b/src/datavisualizationqml/declarativecolor_p.h
new file mode 100644
index 00000000..d197fcf6
--- /dev/null
+++ b/src/datavisualizationqml/declarativecolor_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVECOLOR_P_H
+#define DECLARATIVECOLOR_P_H
+
+#include <private/datavisualizationglobal_p.h>
+#include <QtGui/QColor>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class DeclarativeColor : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+
+ QML_NAMED_ELEMENT(ThemeColor)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ DeclarativeColor(QObject *parent = 0);
+
+ void setColor(const QColor &color);
+ QColor color() const;
+
+Q_SIGNALS:
+ void colorChanged(QColor color);
+
+private:
+ QColor m_color;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativerendernode.cpp b/src/datavisualizationqml/declarativerendernode.cpp
new file mode 100644
index 00000000..f99e1375
--- /dev/null
+++ b/src/datavisualizationqml/declarativerendernode.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativerendernode_p.h"
+#include "abstractdeclarative_p.h"
+#include <QtOpenGL/QOpenGLFramebufferObject>
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeRenderNode::DeclarativeRenderNode(AbstractDeclarative *declarative,
+ const QSharedPointer<QMutex> &nodeMutex)
+ : QSGGeometryNode(),
+ m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4),
+ m_texture(0),
+ m_declarative(declarative),
+ m_controller(0),
+ m_fbo(0),
+ m_multisampledFBO(0),
+ m_window(0),
+ m_samples(0),
+ m_dirtyFBO(false)
+{
+ m_nodeMutex = nodeMutex;
+ setMaterial(&m_material);
+ setOpaqueMaterial(&m_materialO);
+ setGeometry(&m_geometry);
+ setFlag(UsePreprocess);
+}
+
+DeclarativeRenderNode::~DeclarativeRenderNode()
+{
+ delete m_fbo;
+ delete m_multisampledFBO;
+ delete m_texture;
+
+ m_nodeMutex.clear();
+}
+
+void DeclarativeRenderNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+
+ m_size = size;
+ m_dirtyFBO = true;
+ markDirty(DirtyGeometry);
+}
+
+void DeclarativeRenderNode::update()
+{
+ if (m_dirtyFBO) {
+ updateFBO();
+ m_dirtyFBO = false;
+ }
+}
+
+void DeclarativeRenderNode::updateFBO()
+{
+ m_declarative->activateOpenGLContext(m_window);
+
+ if (m_fbo)
+ delete m_fbo;
+
+ m_fbo = new QOpenGLFramebufferObject(m_size);
+ m_fbo->setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+
+ // Multisampled
+ if (m_multisampledFBO) {
+ delete m_multisampledFBO;
+ m_multisampledFBO = 0;
+ }
+ if (m_samples > 0) {
+ QOpenGLFramebufferObjectFormat multisampledFrambufferFormat;
+ multisampledFrambufferFormat.setSamples(m_samples);
+ multisampledFrambufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+
+ m_multisampledFBO = new QOpenGLFramebufferObject(m_size, multisampledFrambufferFormat);
+ }
+
+ QSGGeometry::updateTexturedRectGeometry(&m_geometry,
+ QRectF(0, 0,
+ m_size.width()
+ / m_controller->scene()->devicePixelRatio(),
+ m_size.height()
+ / m_controller->scene()->devicePixelRatio()),
+ QRectF(0, 1, 1, -1));
+
+ delete m_texture;
+ const uint id = m_fbo->texture();
+ m_texture = QNativeInterface::QSGOpenGLTexture::fromNative(id, m_window, m_size);
+ m_material.setTexture(m_texture);
+ m_materialO.setTexture(m_texture);
+
+ m_declarative->doneOpenGLContext(m_window);
+}
+
+void DeclarativeRenderNode::setQuickWindow(QQuickWindow *window)
+{
+ Q_ASSERT(window);
+
+ m_window = window;
+}
+
+void DeclarativeRenderNode::setController(Abstract3DController *controller)
+{
+ QMutexLocker locker(m_nodeMutex.data());
+ m_controller = controller;
+ if (m_controller) {
+ connect(m_controller, &QObject::destroyed,
+ this, &DeclarativeRenderNode::handleControllerDestroyed, Qt::DirectConnection);
+ }
+}
+
+void DeclarativeRenderNode::setSamples(int samples)
+{
+ if (m_samples == samples)
+ return;
+
+ m_samples = samples;
+ m_dirtyFBO = true;
+}
+
+void DeclarativeRenderNode::preprocess()
+{
+ QMutexLocker locker(m_nodeMutex.data());
+
+ if (!m_controller)
+ return;
+
+ QOpenGLFramebufferObject *targetFBO;
+ if (m_samples > 0)
+ targetFBO = m_multisampledFBO;
+ else
+ targetFBO = m_fbo;
+
+ m_declarative->activateOpenGLContext(m_window);
+
+ targetFBO->bind();
+ // Render scene here
+ m_controller->render(targetFBO->handle());
+
+ targetFBO->release();
+
+ if (m_samples > 0)
+ QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFBO);
+
+ m_declarative->doneOpenGLContext(m_window);
+}
+
+// This function is called within m_nodeMutex lock
+void DeclarativeRenderNode::handleControllerDestroyed()
+{
+ m_controller = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativerendernode_p.h b/src/datavisualizationqml/declarativerendernode_p.h
new file mode 100644
index 00000000..28cb0538
--- /dev/null
+++ b/src/datavisualizationqml/declarativerendernode_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVERENDERNODE_P_H
+#define DECLARATIVERENDERNODE_P_H
+
+#include <private/datavisualizationglobal_p.h>
+
+#include <QtQuick/QSGGeometryNode>
+#include <QtQuick/QSGTextureMaterial>
+#include <QtQuick/QQuickWindow>
+#include <QtCore/QMutex>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class Abstract3DController;
+class AbstractDeclarative;
+
+class DeclarativeRenderNode : public QObject, public QSGGeometryNode
+{
+ Q_OBJECT
+public:
+ DeclarativeRenderNode(AbstractDeclarative *declarative,
+ const QSharedPointer<QMutex> &nodeMutex);
+ ~DeclarativeRenderNode();
+
+ void setSize(const QSize &size);
+ QSize size() const { return m_size; }
+
+ void update();
+ void updateFBO();
+
+ void setController(Abstract3DController *controller);
+ void setQuickWindow(QQuickWindow *window);
+ void setSamples(int samples);
+
+ void preprocess() override;
+
+public Q_SLOTS:
+ void handleControllerDestroyed();
+
+private:
+ QSGTextureMaterial m_material;
+ QSGOpaqueTextureMaterial m_materialO;
+ QSGGeometry m_geometry;
+ QSGTexture *m_texture;
+ QSize m_size;
+
+ AbstractDeclarative *m_declarative;
+ Abstract3DController *m_controller;
+ QOpenGLFramebufferObject *m_fbo;
+ QOpenGLFramebufferObject *m_multisampledFBO;
+ QQuickWindow *m_window;
+ int m_samples;
+
+ bool m_dirtyFBO;
+
+ QSharedPointer<QMutex> m_nodeMutex;
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativescatter.cpp b/src/datavisualizationqml/declarativescatter.cpp
new file mode 100644
index 00000000..1417bc6d
--- /dev/null
+++ b/src/datavisualizationqml/declarativescatter.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativescatter_p.h"
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeScatter::DeclarativeScatter(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_scatterController(0)
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // Create the shared component on the main GUI thread.
+ m_scatterController = new Scatter3DController(boundingRect().toRect(), new Declarative3DScene);
+ setSharedController(m_scatterController);
+
+ QObject::connect(m_scatterController, &Scatter3DController::selectedSeriesChanged,
+ this, &DeclarativeScatter::selectedSeriesChanged);
+}
+
+DeclarativeScatter::~DeclarativeScatter()
+{
+ QMutexLocker locker(m_nodeMutex.data());
+ const QMutexLocker locker2(mutex());
+ delete m_scatterController;
+}
+
+QValue3DAxis *DeclarativeScatter::axisX() const
+{
+ return static_cast<QValue3DAxis *>(m_scatterController->axisX());
+}
+
+void DeclarativeScatter::setAxisX(QValue3DAxis *axis)
+{
+ m_scatterController->setAxisX(axis);
+}
+
+QValue3DAxis *DeclarativeScatter::axisY() const
+{
+ return static_cast<QValue3DAxis *>(m_scatterController->axisY());
+}
+
+void DeclarativeScatter::setAxisY(QValue3DAxis *axis)
+{
+ m_scatterController->setAxisY(axis);
+}
+
+QValue3DAxis *DeclarativeScatter::axisZ() const
+{
+ return static_cast<QValue3DAxis *>(m_scatterController->axisZ());
+}
+
+void DeclarativeScatter::setAxisZ(QValue3DAxis *axis)
+{
+ m_scatterController->setAxisZ(axis);
+}
+
+QScatter3DSeries *DeclarativeScatter::selectedSeries() const
+{
+ return m_scatterController->selectedSeries();
+}
+
+QQmlListProperty<QScatter3DSeries> DeclarativeScatter::seriesList()
+{
+ return QQmlListProperty<QScatter3DSeries>(this, this,
+ &DeclarativeScatter::appendSeriesFunc,
+ &DeclarativeScatter::countSeriesFunc,
+ &DeclarativeScatter::atSeriesFunc,
+ &DeclarativeScatter::clearSeriesFunc);
+}
+
+void DeclarativeScatter::appendSeriesFunc(QQmlListProperty<QScatter3DSeries> *list,
+ QScatter3DSeries *series)
+{
+ reinterpret_cast<DeclarativeScatter *>(list->data)->addSeries(series);
+}
+
+qsizetype DeclarativeScatter::countSeriesFunc(QQmlListProperty<QScatter3DSeries> *list)
+{
+ return reinterpret_cast<DeclarativeScatter *>(list->data)->m_scatterController->scatterSeriesList().size();
+}
+
+QScatter3DSeries *DeclarativeScatter::atSeriesFunc(QQmlListProperty<QScatter3DSeries> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeScatter *>(list->data)->m_scatterController->scatterSeriesList().at(index);
+}
+
+void DeclarativeScatter::clearSeriesFunc(QQmlListProperty<QScatter3DSeries> *list)
+{
+ DeclarativeScatter *declScatter = reinterpret_cast<DeclarativeScatter *>(list->data);
+ QList<QScatter3DSeries *> realList = declScatter->m_scatterController->scatterSeriesList();
+ int count = realList.size();
+ for (int i = 0; i < count; i++)
+ declScatter->removeSeries(realList.at(i));
+}
+
+void DeclarativeScatter::addSeries(QScatter3DSeries *series)
+{
+ m_scatterController->addSeries(series);
+}
+
+void DeclarativeScatter::removeSeries(QScatter3DSeries *series)
+{
+ m_scatterController->removeSeries(series);
+ series->setParent(this); // Reparent as removing will leave series parentless
+}
+
+void DeclarativeScatter::handleAxisXChanged(QAbstract3DAxis *axis)
+{
+ emit axisXChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+void DeclarativeScatter::handleAxisYChanged(QAbstract3DAxis *axis)
+{
+ emit axisYChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+void DeclarativeScatter::handleAxisZChanged(QAbstract3DAxis *axis)
+{
+ emit axisZChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativescatter_p.h b/src/datavisualizationqml/declarativescatter_p.h
new file mode 100644
index 00000000..18848e0b
--- /dev/null
+++ b/src/datavisualizationqml/declarativescatter_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVESCATTER_P_H
+#define DECLARATIVESCATTER_P_H
+
+#include "abstractdeclarative_p.h"
+#include "qscatter3dseries.h"
+
+#include <private/datavisualizationglobal_p.h>
+#include <private/scatter3dcontroller_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class DeclarativeScatter : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
+ Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
+ Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
+ Q_PROPERTY(QScatter3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
+ Q_PROPERTY(QQmlListProperty<QScatter3DSeries> seriesList READ seriesList)
+ Q_CLASSINFO("DefaultProperty", "seriesList")
+
+ QML_NAMED_ELEMENT(Scatter3D)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ explicit DeclarativeScatter(QQuickItem *parent = 0);
+ ~DeclarativeScatter();
+
+ QValue3DAxis *axisX() const;
+ void setAxisX(QValue3DAxis *axis);
+ QValue3DAxis *axisY() const;
+ void setAxisY(QValue3DAxis *axis);
+ QValue3DAxis *axisZ() const;
+ void setAxisZ(QValue3DAxis *axis);
+
+ QQmlListProperty<QScatter3DSeries> seriesList();
+ static void appendSeriesFunc(QQmlListProperty<QScatter3DSeries> *list, QScatter3DSeries *series);
+ static qsizetype countSeriesFunc(QQmlListProperty<QScatter3DSeries> *list);
+ static QScatter3DSeries *atSeriesFunc(QQmlListProperty<QScatter3DSeries> *list, qsizetype index);
+ static void clearSeriesFunc(QQmlListProperty<QScatter3DSeries> *list);
+ Q_INVOKABLE void addSeries(QScatter3DSeries *series);
+ Q_INVOKABLE void removeSeries(QScatter3DSeries *series);
+
+ QScatter3DSeries *selectedSeries() const;
+
+public Q_SLOTS:
+ void handleAxisXChanged(QAbstract3DAxis *axis) override;
+ void handleAxisYChanged(QAbstract3DAxis *axis) override;
+ void handleAxisZChanged(QAbstract3DAxis *axis) override;
+
+Q_SIGNALS:
+ void axisXChanged(QValue3DAxis *axis);
+ void axisYChanged(QValue3DAxis *axis);
+ void axisZChanged(QValue3DAxis *axis);
+ void selectedSeriesChanged(QScatter3DSeries *series);
+
+protected:
+ Scatter3DController *m_scatterController;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativescene.cpp b/src/datavisualizationqml/declarativescene.cpp
new file mode 100644
index 00000000..f4e5ae00
--- /dev/null
+++ b/src/datavisualizationqml/declarativescene.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativescene_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Declarative3DScene::Declarative3DScene(QObject *parent)
+ : Q3DScene(parent)
+{
+ QObject::connect(this, &Q3DScene::selectionQueryPositionChanged, this,
+ &Declarative3DScene::selectionQueryPositionChanged);
+}
+
+Declarative3DScene::~Declarative3DScene()
+{
+}
+
+void Declarative3DScene::setSelectionQueryPosition(const QPointF &point)
+{
+ Q3DScene::setSelectionQueryPosition(point.toPoint());
+}
+
+QPointF Declarative3DScene::selectionQueryPosition() const
+{
+ return QPointF(Q3DScene::selectionQueryPosition());
+}
+
+QPoint Declarative3DScene::invalidSelectionPoint() const
+{
+ return Q3DScene::invalidSelectionPoint();
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativescene_p.h b/src/datavisualizationqml/declarativescene_p.h
new file mode 100644
index 00000000..26591d43
--- /dev/null
+++ b/src/datavisualizationqml/declarativescene_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVESCENE_P_H
+#define DECLARATIVESCENE_P_H
+
+#include <QtQml/qqml.h>
+#include <private/datavisualizationglobal_p.h>
+#include <QtDataVisualization/q3dscene.h>
+
+QT_BEGIN_NAMESPACE
+
+class Declarative3DScene : public Q3DScene
+{
+ Q_OBJECT
+ // This property is overloaded to use QPointF instead of QPoint to work around qml bug
+ // where Qt.point(0, 0) can't be assigned due to error "Cannot assign QPointF to QPoint".
+ Q_PROPERTY(QPointF selectionQueryPosition READ selectionQueryPosition WRITE setSelectionQueryPosition NOTIFY selectionQueryPositionChanged)
+ // This is static method in parent class, overload as constant property for qml.
+ Q_PROPERTY(QPoint invalidSelectionPoint READ invalidSelectionPoint CONSTANT)
+
+ QML_NAMED_ELEMENT(Scene3D)
+ QML_ADDED_IN_VERSION(1, 0)
+ QML_UNCREATABLE("Trying to create uncreatable: Scene3D.")
+
+public:
+ Declarative3DScene(QObject *parent = 0);
+ virtual ~Declarative3DScene();
+
+ void setSelectionQueryPosition(const QPointF &point);
+ QPointF selectionQueryPosition() const;
+ QPoint invalidSelectionPoint() const;
+
+Q_SIGNALS:
+ void selectionQueryPositionChanged(const QPointF position);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativeseries.cpp b/src/datavisualizationqml/declarativeseries.cpp
new file mode 100644
index 00000000..38263a32
--- /dev/null
+++ b/src/datavisualizationqml/declarativeseries.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativeseries_p.h"
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_NAMESPACE
+
+static void setSeriesGradient(QAbstract3DSeries *series, const ColorGradient &gradient,
+ GradientType type)
+{
+ QLinearGradient newGradient;
+ QGradientStops stops;
+ QList<ColorGradientStop *> qmlstops = gradient.m_stops;
+
+ // Get sorted gradient stops
+ for (int i = 0; i < qmlstops.size(); i++) {
+ int j = 0;
+ while (j < stops.size() && stops.at(j).first < qmlstops[i]->position())
+ j++;
+ stops.insert(j, QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color()));
+ }
+
+ newGradient.setStops(stops);
+ switch (type) {
+ case GradientTypeBase:
+ series->setBaseGradient(newGradient);
+ break;
+ case GradientTypeSingle:
+ series->setSingleHighlightGradient(newGradient);
+ break;
+ case GradientTypeMulti:
+ series->setMultiHighlightGradient(newGradient);
+ break;
+ default: // Never goes here
+ break;
+ }
+}
+
+static void connectSeriesGradient(QAbstract3DSeries *series, ColorGradient *newGradient,
+ GradientType type, ColorGradient **memberGradient)
+{
+ // connect new / disconnect old
+ if (newGradient != *memberGradient) {
+ if (*memberGradient)
+ QObject::disconnect(*memberGradient, 0, series, 0);
+
+ *memberGradient = newGradient;
+
+ int updatedIndex = newGradient->metaObject()->indexOfSignal("updated()");
+ QMetaMethod updateFunction = newGradient->metaObject()->method(updatedIndex);
+ int handleIndex = -1;
+ switch (type) {
+ case GradientTypeBase:
+ handleIndex = series->metaObject()->indexOfSlot("handleBaseGradientUpdate()");
+ break;
+ case GradientTypeSingle:
+ handleIndex = series->metaObject()->indexOfSlot("handleSingleHighlightGradientUpdate()");
+ break;
+ case GradientTypeMulti:
+ handleIndex = series->metaObject()->indexOfSlot("handleMultiHighlightGradientUpdate()");
+ break;
+ default: // Never goes here
+ break;
+ }
+ QMetaMethod handleFunction = series->metaObject()->method(handleIndex);
+
+ if (*memberGradient)
+ QObject::connect(*memberGradient, updateFunction, series, handleFunction);
+ }
+
+ if (*memberGradient)
+ setSeriesGradient(series, **memberGradient, type);
+}
+
+DeclarativeBar3DSeries::DeclarativeBar3DSeries(QObject *parent)
+ : QBar3DSeries(parent),
+ m_baseGradient(0),
+ m_singleHighlightGradient(0),
+ m_multiHighlightGradient(0)
+{
+ QObject::connect(this, &QBar3DSeries::selectedBarChanged, this,
+ &DeclarativeBar3DSeries::selectedBarChanged);
+}
+
+DeclarativeBar3DSeries::~DeclarativeBar3DSeries()
+{
+}
+
+QQmlListProperty<QObject> DeclarativeBar3DSeries::seriesChildren()
+{
+ return QQmlListProperty<QObject>(this, this, &DeclarativeBar3DSeries::appendSeriesChildren
+ , 0, 0, 0);
+}
+
+void DeclarativeBar3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element)
+{
+ QBarDataProxy *proxy = qobject_cast<QBarDataProxy *>(element);
+ if (proxy)
+ reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->setDataProxy(proxy);
+}
+
+void DeclarativeBar3DSeries::setSelectedBar(const QPointF &position)
+{
+ QBar3DSeries::setSelectedBar(position.toPoint());
+}
+
+QPointF DeclarativeBar3DSeries::selectedBar() const
+{
+ return QPointF(QBar3DSeries::selectedBar());
+}
+
+QPointF DeclarativeBar3DSeries::invalidSelectionPosition() const
+{
+ return QPointF(QBar3DSeries::invalidSelectionPosition());
+}
+
+void DeclarativeBar3DSeries::setBaseGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
+}
+
+ColorGradient *DeclarativeBar3DSeries::baseGradient() const
+{
+ return m_baseGradient;
+}
+
+void DeclarativeBar3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
+}
+
+ColorGradient *DeclarativeBar3DSeries::singleHighlightGradient() const
+{
+ return m_singleHighlightGradient;
+}
+
+void DeclarativeBar3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
+}
+
+ColorGradient *DeclarativeBar3DSeries::multiHighlightGradient() const
+{
+ return m_multiHighlightGradient;
+}
+
+void DeclarativeBar3DSeries::handleBaseGradientUpdate()
+{
+ if (m_baseGradient)
+ setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
+}
+
+void DeclarativeBar3DSeries::handleSingleHighlightGradientUpdate()
+{
+ if (m_singleHighlightGradient)
+ setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
+}
+
+void DeclarativeBar3DSeries::handleMultiHighlightGradientUpdate()
+{
+ if (m_multiHighlightGradient)
+ setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
+}
+
+DeclarativeScatter3DSeries::DeclarativeScatter3DSeries(QObject *parent)
+ : QScatter3DSeries(parent),
+ m_baseGradient(0),
+ m_singleHighlightGradient(0),
+ m_multiHighlightGradient(0)
+{
+}
+
+DeclarativeScatter3DSeries::~DeclarativeScatter3DSeries()
+{
+}
+
+QQmlListProperty<QObject> DeclarativeScatter3DSeries::seriesChildren()
+{
+ return QQmlListProperty<QObject>(this, this, &DeclarativeScatter3DSeries::appendSeriesChildren
+ , 0, 0, 0);
+}
+
+void DeclarativeScatter3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
+ QObject *element)
+{
+ QScatterDataProxy *proxy = qobject_cast<QScatterDataProxy *>(element);
+ if (proxy)
+ reinterpret_cast<DeclarativeScatter3DSeries *>(list->data)->setDataProxy(proxy);
+}
+
+void DeclarativeScatter3DSeries::setBaseGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
+}
+
+ColorGradient *DeclarativeScatter3DSeries::baseGradient() const
+{
+ return m_baseGradient;
+}
+
+void DeclarativeScatter3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
+}
+
+ColorGradient *DeclarativeScatter3DSeries::singleHighlightGradient() const
+{
+ return m_singleHighlightGradient;
+}
+
+void DeclarativeScatter3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
+}
+
+ColorGradient *DeclarativeScatter3DSeries::multiHighlightGradient() const
+{
+ return m_multiHighlightGradient;
+}
+
+int DeclarativeScatter3DSeries::invalidSelectionIndex() const
+{
+ return QScatter3DSeries::invalidSelectionIndex();
+}
+
+void DeclarativeScatter3DSeries::handleBaseGradientUpdate()
+{
+ if (m_baseGradient)
+ setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
+}
+
+void DeclarativeScatter3DSeries::handleSingleHighlightGradientUpdate()
+{
+ if (m_singleHighlightGradient)
+ setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
+}
+
+void DeclarativeScatter3DSeries::handleMultiHighlightGradientUpdate()
+{
+ if (m_multiHighlightGradient)
+ setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
+}
+
+DeclarativeSurface3DSeries::DeclarativeSurface3DSeries(QObject *parent)
+ : QSurface3DSeries(parent),
+ m_baseGradient(0),
+ m_singleHighlightGradient(0),
+ m_multiHighlightGradient(0)
+{
+ QObject::connect(this, &QSurface3DSeries::selectedPointChanged, this,
+ &DeclarativeSurface3DSeries::selectedPointChanged);
+}
+
+DeclarativeSurface3DSeries::~DeclarativeSurface3DSeries()
+{
+}
+
+void DeclarativeSurface3DSeries::setSelectedPoint(const QPointF &position)
+{
+ QSurface3DSeries::setSelectedPoint(position.toPoint());
+}
+
+QPointF DeclarativeSurface3DSeries::selectedPoint() const
+{
+ return QPointF(QSurface3DSeries::selectedPoint());
+}
+
+QPointF DeclarativeSurface3DSeries::invalidSelectionPosition() const
+{
+ return QPointF(QSurface3DSeries::invalidSelectionPosition());
+}
+
+QQmlListProperty<QObject> DeclarativeSurface3DSeries::seriesChildren()
+{
+ return QQmlListProperty<QObject>(this, this, &DeclarativeSurface3DSeries::appendSeriesChildren
+ , 0, 0, 0);
+}
+
+void DeclarativeSurface3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
+ QObject *element)
+{
+ QSurfaceDataProxy *proxy = qobject_cast<QSurfaceDataProxy *>(element);
+ if (proxy)
+ reinterpret_cast<DeclarativeSurface3DSeries *>(list->data)->setDataProxy(proxy);
+}
+
+void DeclarativeSurface3DSeries::setBaseGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
+}
+
+ColorGradient *DeclarativeSurface3DSeries::baseGradient() const
+{
+ return m_baseGradient;
+}
+
+void DeclarativeSurface3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
+}
+
+ColorGradient *DeclarativeSurface3DSeries::singleHighlightGradient() const
+{
+ return m_singleHighlightGradient;
+}
+
+void DeclarativeSurface3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
+{
+ connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
+}
+
+ColorGradient *DeclarativeSurface3DSeries::multiHighlightGradient() const
+{
+ return m_multiHighlightGradient;
+}
+
+void DeclarativeSurface3DSeries::handleBaseGradientUpdate()
+{
+ if (m_baseGradient)
+ setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
+}
+
+void DeclarativeSurface3DSeries::handleSingleHighlightGradientUpdate()
+{
+ if (m_singleHighlightGradient)
+ setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
+}
+
+void DeclarativeSurface3DSeries::handleMultiHighlightGradientUpdate()
+{
+ if (m_multiHighlightGradient)
+ setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativeseries_p.h b/src/datavisualizationqml/declarativeseries_p.h
new file mode 100644
index 00000000..115e67e0
--- /dev/null
+++ b/src/datavisualizationqml/declarativeseries_p.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVESERIES_P_H
+#define DECLARATIVESERIES_P_H
+
+#include "qbar3dseries.h"
+#include "qscatter3dseries.h"
+#include "qsurface3dseries.h"
+#include "colorgradient_p.h"
+
+#include <private/datavisualizationglobal_p.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+enum GradientType {
+ GradientTypeBase,
+ GradientTypeSingle,
+ GradientTypeMulti
+};
+
+class DeclarativeBar3DSeries : public QBar3DSeries
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<QObject> seriesChildren READ seriesChildren)
+ // This property is overloaded to use QPointF instead of QPoint to work around qml bug
+ // where Qt.point(0, 0) can't be assigned due to error "Cannot assign QPointF to QPoint".
+ Q_PROPERTY(QPointF selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged)
+ // This is static method in parent class, overload as constant property for qml.
+ Q_PROPERTY(QPointF invalidSelectionPosition READ invalidSelectionPosition CONSTANT)
+ Q_PROPERTY(ColorGradient *baseGradient READ baseGradient WRITE setBaseGradient NOTIFY baseGradientChanged)
+ Q_PROPERTY(ColorGradient *singleHighlightGradient READ singleHighlightGradient WRITE setSingleHighlightGradient NOTIFY singleHighlightGradientChanged)
+ Q_PROPERTY(ColorGradient *multiHighlightGradient READ multiHighlightGradient WRITE setMultiHighlightGradient NOTIFY multiHighlightGradientChanged)
+ Q_CLASSINFO("DefaultProperty", "seriesChildren")
+
+ QML_NAMED_ELEMENT(Bar3DSeries)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ DeclarativeBar3DSeries(QObject *parent = 0);
+ virtual ~DeclarativeBar3DSeries();
+
+ QQmlListProperty<QObject> seriesChildren();
+ static void appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element);
+
+ void setSelectedBar(const QPointF &position);
+ QPointF selectedBar() const;
+ QPointF invalidSelectionPosition() const;
+
+ void setBaseGradient(ColorGradient *gradient);
+ ColorGradient *baseGradient() const;
+ void setSingleHighlightGradient(ColorGradient *gradient);
+ ColorGradient *singleHighlightGradient() const;
+ void setMultiHighlightGradient(ColorGradient *gradient);
+ ColorGradient *multiHighlightGradient() const;
+
+public Q_SLOTS:
+ void handleBaseGradientUpdate();
+ void handleSingleHighlightGradientUpdate();
+ void handleMultiHighlightGradientUpdate();
+
+Q_SIGNALS:
+ void selectedBarChanged(QPointF position);
+ void baseGradientChanged(ColorGradient *gradient);
+ void singleHighlightGradientChanged(ColorGradient *gradient);
+ void multiHighlightGradientChanged(ColorGradient *gradient);
+
+private:
+ ColorGradient *m_baseGradient; // Not owned
+ ColorGradient *m_singleHighlightGradient; // Not owned
+ ColorGradient *m_multiHighlightGradient; // Not owned
+};
+
+class DeclarativeScatter3DSeries : public QScatter3DSeries
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<QObject> seriesChildren READ seriesChildren)
+ Q_PROPERTY(ColorGradient *baseGradient READ baseGradient WRITE setBaseGradient NOTIFY baseGradientChanged)
+ Q_PROPERTY(ColorGradient *singleHighlightGradient READ singleHighlightGradient WRITE setSingleHighlightGradient NOTIFY singleHighlightGradientChanged)
+ Q_PROPERTY(ColorGradient *multiHighlightGradient READ multiHighlightGradient WRITE setMultiHighlightGradient NOTIFY multiHighlightGradientChanged)
+ // This is static method in parent class, overload as constant property for qml.
+ Q_PROPERTY(int invalidSelectionIndex READ invalidSelectionIndex CONSTANT)
+ Q_CLASSINFO("DefaultProperty", "seriesChildren")
+
+ QML_NAMED_ELEMENT(Scatter3DSeries)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ DeclarativeScatter3DSeries(QObject *parent = 0);
+ virtual ~DeclarativeScatter3DSeries();
+
+ QQmlListProperty<QObject> seriesChildren();
+ static void appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element);
+
+ void setBaseGradient(ColorGradient *gradient);
+ ColorGradient *baseGradient() const;
+ void setSingleHighlightGradient(ColorGradient *gradient);
+ ColorGradient *singleHighlightGradient() const;
+ void setMultiHighlightGradient(ColorGradient *gradient);
+ ColorGradient *multiHighlightGradient() const;
+
+ int invalidSelectionIndex() const;
+
+public Q_SLOTS:
+ void handleBaseGradientUpdate();
+ void handleSingleHighlightGradientUpdate();
+ void handleMultiHighlightGradientUpdate();
+
+Q_SIGNALS:
+ void baseGradientChanged(ColorGradient *gradient);
+ void singleHighlightGradientChanged(ColorGradient *gradient);
+ void multiHighlightGradientChanged(ColorGradient *gradient);
+
+private:
+ ColorGradient *m_baseGradient; // Not owned
+ ColorGradient *m_singleHighlightGradient; // Not owned
+ ColorGradient *m_multiHighlightGradient; // Not owned
+};
+
+class DeclarativeSurface3DSeries : public QSurface3DSeries
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<QObject> seriesChildren READ seriesChildren)
+ // This property is overloaded to use QPointF instead of QPoint to work around qml bug
+ // where Qt.point(0, 0) can't be assigned due to error "Cannot assign QPointF to QPoint".
+ Q_PROPERTY(QPointF selectedPoint READ selectedPoint WRITE setSelectedPoint NOTIFY selectedPointChanged)
+ // This is static method in parent class, overload as constant property for qml.
+ Q_PROPERTY(QPointF invalidSelectionPosition READ invalidSelectionPosition CONSTANT)
+ Q_PROPERTY(ColorGradient *baseGradient READ baseGradient WRITE setBaseGradient NOTIFY baseGradientChanged)
+ Q_PROPERTY(ColorGradient *singleHighlightGradient READ singleHighlightGradient WRITE setSingleHighlightGradient NOTIFY singleHighlightGradientChanged)
+ Q_PROPERTY(ColorGradient *multiHighlightGradient READ multiHighlightGradient WRITE setMultiHighlightGradient NOTIFY multiHighlightGradientChanged)
+ Q_CLASSINFO("DefaultProperty", "seriesChildren")
+
+ QML_NAMED_ELEMENT(Surface3DSeries)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ DeclarativeSurface3DSeries(QObject *parent = 0);
+ virtual ~DeclarativeSurface3DSeries();
+
+ void setSelectedPoint(const QPointF &position);
+ QPointF selectedPoint() const;
+ QPointF invalidSelectionPosition() const;
+
+ QQmlListProperty<QObject> seriesChildren();
+ static void appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element);
+
+ void setBaseGradient(ColorGradient *gradient);
+ ColorGradient *baseGradient() const;
+ void setSingleHighlightGradient(ColorGradient *gradient);
+ ColorGradient *singleHighlightGradient() const;
+ void setMultiHighlightGradient(ColorGradient *gradient);
+ ColorGradient *multiHighlightGradient() const;
+
+public Q_SLOTS:
+ void handleBaseGradientUpdate();
+ void handleSingleHighlightGradientUpdate();
+ void handleMultiHighlightGradientUpdate();
+
+Q_SIGNALS:
+ void selectedPointChanged(QPointF position);
+ void baseGradientChanged(ColorGradient *gradient);
+ void singleHighlightGradientChanged(ColorGradient *gradient);
+ void multiHighlightGradientChanged(ColorGradient *gradient);
+
+private:
+ ColorGradient *m_baseGradient; // Not owned
+ ColorGradient *m_singleHighlightGradient; // Not owned
+ ColorGradient *m_multiHighlightGradient; // Not owned
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativesurface.cpp b/src/datavisualizationqml/declarativesurface.cpp
new file mode 100644
index 00000000..d422992a
--- /dev/null
+++ b/src/datavisualizationqml/declarativesurface.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativesurface_p.h"
+#include <QtCore/QMutexLocker>
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeSurface::DeclarativeSurface(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_surfaceController(0)
+{
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // Create the shared component on the main GUI thread.
+ m_surfaceController = new Surface3DController(boundingRect().toRect(), new Declarative3DScene);
+ setSharedController(m_surfaceController);
+
+ QObject::connect(m_surfaceController, &Surface3DController::selectedSeriesChanged,
+ this, &DeclarativeSurface::selectedSeriesChanged);
+ QObject::connect(m_surfaceController, &Surface3DController::flipHorizontalGridChanged,
+ this, &DeclarativeSurface::flipHorizontalGridChanged);
+}
+
+DeclarativeSurface::~DeclarativeSurface()
+{
+ QMutexLocker locker(m_nodeMutex.data());
+ const QMutexLocker locker2(mutex());
+ delete m_surfaceController;
+}
+
+QValue3DAxis *DeclarativeSurface::axisX() const
+{
+ return static_cast<QValue3DAxis *>(m_surfaceController->axisX());
+}
+
+void DeclarativeSurface::setAxisX(QValue3DAxis *axis)
+{
+ m_surfaceController->setAxisX(axis);
+}
+
+QValue3DAxis *DeclarativeSurface::axisY() const
+{
+ return static_cast<QValue3DAxis *>(m_surfaceController->axisY());
+}
+
+void DeclarativeSurface::setAxisY(QValue3DAxis *axis)
+{
+ m_surfaceController->setAxisY(axis);
+}
+
+QValue3DAxis *DeclarativeSurface::axisZ() const
+{
+ return static_cast<QValue3DAxis *>(m_surfaceController->axisZ());
+}
+
+void DeclarativeSurface::setAxisZ(QValue3DAxis *axis)
+{
+ m_surfaceController->setAxisZ(axis);
+}
+
+QSurface3DSeries *DeclarativeSurface::selectedSeries() const
+{
+ return m_surfaceController->selectedSeries();
+}
+
+void DeclarativeSurface::setFlipHorizontalGrid(bool flip)
+{
+ m_surfaceController->setFlipHorizontalGrid(flip);
+}
+
+bool DeclarativeSurface::flipHorizontalGrid() const
+{
+ return m_surfaceController->flipHorizontalGrid();
+}
+
+QQmlListProperty<QSurface3DSeries> DeclarativeSurface::seriesList()
+{
+ return QQmlListProperty<QSurface3DSeries>(this, this,
+ &DeclarativeSurface::appendSeriesFunc,
+ &DeclarativeSurface::countSeriesFunc,
+ &DeclarativeSurface::atSeriesFunc,
+ &DeclarativeSurface::clearSeriesFunc);
+}
+
+void DeclarativeSurface::appendSeriesFunc(QQmlListProperty<QSurface3DSeries> *list,
+ QSurface3DSeries *series)
+{
+ reinterpret_cast<DeclarativeSurface *>(list->data)->addSeries(series);
+}
+
+qsizetype DeclarativeSurface::countSeriesFunc(QQmlListProperty<QSurface3DSeries> *list)
+{
+ return reinterpret_cast<DeclarativeSurface *>(list->data)->m_surfaceController->surfaceSeriesList().size();
+}
+
+QSurface3DSeries *DeclarativeSurface::atSeriesFunc(QQmlListProperty<QSurface3DSeries> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeSurface *>(list->data)->m_surfaceController->surfaceSeriesList().at(index);
+}
+
+void DeclarativeSurface::clearSeriesFunc(QQmlListProperty<QSurface3DSeries> *list)
+{
+ DeclarativeSurface *declSurface = reinterpret_cast<DeclarativeSurface *>(list->data);
+ QList<QSurface3DSeries *> realList = declSurface->m_surfaceController->surfaceSeriesList();
+ int count = realList.size();
+ for (int i = 0; i < count; i++)
+ declSurface->removeSeries(realList.at(i));
+}
+
+void DeclarativeSurface::addSeries(QSurface3DSeries *series)
+{
+ m_surfaceController->addSeries(series);
+}
+
+void DeclarativeSurface::removeSeries(QSurface3DSeries *series)
+{
+ m_surfaceController->removeSeries(series);
+ series->setParent(this); // Reparent as removing will leave series parentless
+}
+
+void DeclarativeSurface::handleAxisXChanged(QAbstract3DAxis *axis)
+{
+ emit axisXChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+void DeclarativeSurface::handleAxisYChanged(QAbstract3DAxis *axis)
+{
+ emit axisYChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+void DeclarativeSurface::handleAxisZChanged(QAbstract3DAxis *axis)
+{
+ emit axisZChanged(static_cast<QValue3DAxis *>(axis));
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativesurface_p.h b/src/datavisualizationqml/declarativesurface_p.h
new file mode 100644
index 00000000..71f3c470
--- /dev/null
+++ b/src/datavisualizationqml/declarativesurface_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVESURFACE_P_H
+#define DECLARATIVESURFACE_P_H
+
+#include "abstractdeclarative_p.h"
+#include "qsurface3dseries.h"
+
+#include <private/datavisualizationglobal_p.h>
+#include <private/surface3dcontroller_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class DeclarativeSurface : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged)
+ Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged)
+ Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged)
+ Q_PROPERTY(QSurface3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged)
+ Q_PROPERTY(QQmlListProperty<QSurface3DSeries> seriesList READ seriesList)
+ Q_PROPERTY(bool flipHorizontalGrid READ flipHorizontalGrid WRITE setFlipHorizontalGrid NOTIFY flipHorizontalGridChanged REVISION(1, 2))
+ Q_CLASSINFO("DefaultProperty", "seriesList")
+
+ QML_NAMED_ELEMENT(Surface3D)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ explicit DeclarativeSurface(QQuickItem *parent = 0);
+ ~DeclarativeSurface();
+
+ QValue3DAxis *axisX() const;
+ void setAxisX(QValue3DAxis *axis);
+ QValue3DAxis *axisY() const;
+ void setAxisY(QValue3DAxis *axis);
+ QValue3DAxis *axisZ() const;
+ void setAxisZ(QValue3DAxis *axis);
+
+ QQmlListProperty<QSurface3DSeries> seriesList();
+ static void appendSeriesFunc(QQmlListProperty<QSurface3DSeries> *list, QSurface3DSeries *series);
+ static qsizetype countSeriesFunc(QQmlListProperty<QSurface3DSeries> *list);
+ static QSurface3DSeries *atSeriesFunc(QQmlListProperty<QSurface3DSeries> *list, qsizetype index);
+ static void clearSeriesFunc(QQmlListProperty<QSurface3DSeries> *list);
+ Q_INVOKABLE void addSeries(QSurface3DSeries *series);
+ Q_INVOKABLE void removeSeries(QSurface3DSeries *series);
+
+ QSurface3DSeries *selectedSeries() const;
+ void setFlipHorizontalGrid(bool flip);
+ bool flipHorizontalGrid() const;
+
+public Q_SLOTS:
+ void handleAxisXChanged(QAbstract3DAxis *axis) override;
+ void handleAxisYChanged(QAbstract3DAxis *axis) override;
+ void handleAxisZChanged(QAbstract3DAxis *axis) override;
+
+Q_SIGNALS:
+ void axisXChanged(QValue3DAxis *axis);
+ void axisYChanged(QValue3DAxis *axis);
+ void axisZChanged(QValue3DAxis *axis);
+ void selectedSeriesChanged(QSurface3DSeries *series);
+ Q_REVISION(1, 2) void flipHorizontalGridChanged(bool flip);
+
+private:
+ Surface3DController *m_surfaceController;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/declarativetheme.cpp b/src/datavisualizationqml/declarativetheme.cpp
new file mode 100644
index 00000000..282f14b1
--- /dev/null
+++ b/src/datavisualizationqml/declarativetheme.cpp
@@ -0,0 +1,412 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "declarativetheme_p.h"
+
+QT_BEGIN_NAMESPACE
+
+DeclarativeTheme3D::DeclarativeTheme3D(QObject *parent)
+ : Q3DTheme(parent),
+ m_colors(QList<DeclarativeColor *>()),
+ m_gradients(QList<ColorGradient *>()),
+ m_singleHLGradient(0),
+ m_multiHLGradient(0),
+ m_dummyGradients(false),
+ m_dummyColors(false)
+{
+ connect(this, &Q3DTheme::typeChanged, this, &DeclarativeTheme3D::handleTypeChange);
+}
+
+DeclarativeTheme3D::~DeclarativeTheme3D()
+{
+}
+
+QQmlListProperty<QObject> DeclarativeTheme3D::themeChildren()
+{
+ return QQmlListProperty<QObject>(this, this, &DeclarativeTheme3D::appendThemeChildren,
+ 0, 0, 0);
+}
+
+void DeclarativeTheme3D::appendThemeChildren(QQmlListProperty<QObject> *list, QObject *element)
+{
+ Q_UNUSED(list);
+ Q_UNUSED(element);
+ // Nothing to do, themeChildren is there only to enable scoping gradient items in Theme3D item.
+}
+
+void DeclarativeTheme3D::handleTypeChange(Theme themeType)
+{
+ Q_UNUSED(themeType);
+
+ // Theme changed, disconnect base color/gradient connections
+ if (!m_colors.isEmpty()) {
+ foreach (DeclarativeColor *item, m_colors)
+ disconnect(item, 0, this, 0);
+ m_colors.clear();
+ }
+ if (!m_gradients.isEmpty()) {
+ foreach (ColorGradient *item, m_gradients)
+ disconnect(item, 0, this, 0);
+ m_gradients.clear();
+ }
+}
+
+void DeclarativeTheme3D::handleBaseColorUpdate()
+{
+ int colorCount = m_colors.size();
+ int changed = 0;
+ // Check which one changed
+ DeclarativeColor *color = qobject_cast<DeclarativeColor *>(QObject::sender());
+ for (int i = 0; i < colorCount; i++) {
+ if (color == m_colors.at(i)) {
+ changed = i;
+ break;
+ }
+ }
+ // Update the changed one from the list
+ QList<QColor> list = Q3DTheme::baseColors();
+ list[changed] = m_colors.at(changed)->color();
+ // Set the changed list
+ Q3DTheme::setBaseColors(list);
+}
+
+void DeclarativeTheme3D::handleBaseGradientUpdate()
+{
+ int gradientCount = m_gradients.size();
+ int changed = 0;
+ // Check which one changed
+ ColorGradient *gradient = qobject_cast<ColorGradient *>(QObject::sender());
+ for (int i = 0; i < gradientCount; i++) {
+ if (gradient == m_gradients.at(i)) {
+ changed = i;
+ break;
+ }
+ }
+ // Update the changed one from the list
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ list[changed] = convertGradient(gradient);
+ // Set the changed list
+ Q3DTheme::setBaseGradients(list);
+}
+
+void DeclarativeTheme3D::handleSingleHLGradientUpdate()
+{
+ if (m_singleHLGradient)
+ setThemeGradient(m_singleHLGradient, GradientTypeSingleHL);
+}
+
+void DeclarativeTheme3D::handleMultiHLGradientUpdate()
+{
+ if (m_multiHLGradient)
+ setThemeGradient(m_multiHLGradient, GradientTypeMultiHL);
+}
+
+void DeclarativeTheme3D::setSingleHighlightGradient(ColorGradient *gradient)
+{
+ // connect new / disconnect old
+ if (gradient != m_singleHLGradient) {
+ if (m_singleHLGradient)
+ QObject::disconnect(m_singleHLGradient, 0, this, 0);
+
+ m_singleHLGradient = gradient;
+
+ if (m_singleHLGradient) {
+ QObject::connect(m_singleHLGradient, &ColorGradient::updated, this,
+ &DeclarativeTheme3D::handleSingleHLGradientUpdate);
+ }
+
+ emit singleHighlightGradientChanged(m_singleHLGradient);
+ }
+
+ if (m_singleHLGradient)
+ setThemeGradient(m_singleHLGradient, GradientTypeSingleHL);
+}
+
+ColorGradient *DeclarativeTheme3D::singleHighlightGradient() const
+{
+ return m_singleHLGradient;
+}
+
+void DeclarativeTheme3D::setMultiHighlightGradient(ColorGradient *gradient)
+{
+ // connect new / disconnect old
+ if (gradient != m_multiHLGradient) {
+ if (m_multiHLGradient)
+ QObject::disconnect(m_multiHLGradient, 0, this, 0);
+
+ m_multiHLGradient = gradient;
+
+ if (m_multiHLGradient) {
+ QObject::connect(m_multiHLGradient, &ColorGradient::updated, this,
+ &DeclarativeTheme3D::handleMultiHLGradientUpdate);
+ }
+
+ emit multiHighlightGradientChanged(m_multiHLGradient);
+ }
+
+ if (m_multiHLGradient)
+ setThemeGradient(m_multiHLGradient, GradientTypeMultiHL);
+}
+
+ColorGradient *DeclarativeTheme3D::multiHighlightGradient() const
+{
+ return m_multiHLGradient;
+}
+
+void DeclarativeTheme3D::classBegin()
+{
+ // Turn off predefined type forcing for the duration of initial class construction
+ // so that predefined type customization can be done.
+ d_ptr->setForcePredefinedType(false);
+}
+
+void DeclarativeTheme3D::componentComplete()
+{
+ d_ptr->setForcePredefinedType(true);
+}
+
+
+void DeclarativeTheme3D::setThemeGradient(ColorGradient *gradient, GradientType type)
+{
+ QLinearGradient newGradient = convertGradient(gradient);
+
+ switch (type) {
+ case GradientTypeSingleHL:
+ Q3DTheme::setSingleHighlightGradient(newGradient);
+ break;
+ case GradientTypeMultiHL:
+ Q3DTheme::setMultiHighlightGradient(newGradient);
+ break;
+ default:
+ qWarning("Incorrect usage. Type may be GradientTypeSingleHL or GradientTypeMultiHL.");
+ break;
+ }
+}
+
+QLinearGradient DeclarativeTheme3D::convertGradient(ColorGradient *gradient)
+{
+ QLinearGradient newGradient;
+ QGradientStops stops;
+ QList<ColorGradientStop *> qmlstops = gradient->m_stops;
+
+ // Get sorted gradient stops
+ for (int i = 0; i < qmlstops.size(); i++) {
+ int j = 0;
+ while (j < stops.size() && stops.at(j).first < qmlstops[i]->position())
+ j++;
+ stops.insert(j, QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color()));
+ }
+
+ newGradient.setStops(stops);
+
+ return newGradient;
+}
+
+ColorGradient *DeclarativeTheme3D::convertGradient(const QLinearGradient &gradient)
+{
+ ColorGradient *newGradient = new ColorGradient(this);
+ QGradientStops stops = gradient.stops();
+ ColorGradientStop *qmlstop;
+
+ // Convert stops
+ for (int i = 0; i < stops.size(); i++) {
+ qmlstop = new ColorGradientStop(newGradient);
+ qmlstop->setColor(stops.at(i).second);
+ qmlstop->setPosition(stops.at(i).first);
+ newGradient->m_stops.append(qmlstop);
+ }
+
+ return newGradient;
+}
+
+void DeclarativeTheme3D::addColor(DeclarativeColor *color)
+{
+ if (!color) {
+ qWarning("Color is invalid, use ThemeColor");
+ return;
+ }
+ clearDummyColors();
+ m_colors.append(color);
+ connect(color, &DeclarativeColor::colorChanged,
+ this, &DeclarativeTheme3D::handleBaseColorUpdate);
+ QList<QColor> list = Q3DTheme::baseColors();
+ list.append(color->color());
+ Q3DTheme::setBaseColors(list);
+}
+
+QList<DeclarativeColor *> DeclarativeTheme3D::colorList()
+{
+ if (m_colors.isEmpty()) {
+ // Create dummy ThemeColors from theme's colors
+ m_dummyColors = true;
+ QList<QColor> list = Q3DTheme::baseColors();
+ foreach (QColor item, list) {
+ DeclarativeColor *color = new DeclarativeColor(this);
+ color->setColor(item);
+ m_colors.append(color);
+ connect(color, &DeclarativeColor::colorChanged,
+ this, &DeclarativeTheme3D::handleBaseColorUpdate);
+ }
+ }
+ return m_colors;
+}
+
+void DeclarativeTheme3D::clearColors()
+{
+ clearDummyColors();
+ foreach (DeclarativeColor *item, m_colors)
+ disconnect(item, 0, this, 0);
+ m_colors.clear();
+ Q3DTheme::setBaseColors(QList<QColor>());
+}
+
+void DeclarativeTheme3D::clearDummyColors()
+{
+ if (m_dummyColors) {
+ foreach (DeclarativeColor *item, m_colors)
+ delete item;
+ m_colors.clear();
+ m_dummyColors = false;
+ }
+}
+
+void DeclarativeTheme3D::addGradient(ColorGradient *gradient)
+{
+ if (!gradient) {
+ qWarning("Gradient is invalid, use ColorGradient");
+ return;
+ }
+ clearDummyGradients();
+ m_gradients.append(gradient);
+ connect(gradient, &ColorGradient::updated,
+ this, &DeclarativeTheme3D::handleBaseGradientUpdate);
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ list.append(convertGradient(gradient));
+ Q3DTheme::setBaseGradients(list);
+}
+
+QList<ColorGradient *> DeclarativeTheme3D::gradientList()
+{
+ if (m_gradients.isEmpty()) {
+ // Create dummy ColorGradients from theme's gradients
+ m_dummyGradients = true;
+ QList<QLinearGradient> list = Q3DTheme::baseGradients();
+ foreach (QLinearGradient item, list) {
+ ColorGradient *gradient = convertGradient(item);
+ m_gradients.append(gradient);
+ connect(gradient, &ColorGradient::updated,
+ this, &DeclarativeTheme3D::handleBaseGradientUpdate);
+ }
+ }
+
+ return m_gradients;
+}
+
+void DeclarativeTheme3D::clearGradients()
+{
+ clearDummyGradients();
+ foreach (ColorGradient *item, m_gradients)
+ disconnect(item, 0, this, 0);
+ m_gradients.clear();
+ Q3DTheme::setBaseGradients(QList<QLinearGradient>());
+}
+
+void DeclarativeTheme3D::clearDummyGradients()
+{
+ if (m_dummyGradients) {
+ foreach (ColorGradient *item, m_gradients)
+ delete item;
+ m_gradients.clear();
+ m_dummyGradients = false;
+ }
+}
+
+QQmlListProperty<DeclarativeColor> DeclarativeTheme3D::baseColors()
+{
+ return QQmlListProperty<DeclarativeColor>(this, this,
+ &DeclarativeTheme3D::appendBaseColorsFunc,
+ &DeclarativeTheme3D::countBaseColorsFunc,
+ &DeclarativeTheme3D::atBaseColorsFunc,
+ &DeclarativeTheme3D::clearBaseColorsFunc);
+}
+
+void DeclarativeTheme3D::appendBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ DeclarativeColor *color)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->addColor(color);
+}
+
+qsizetype DeclarativeTheme3D::countBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().size();
+}
+
+DeclarativeColor *DeclarativeTheme3D::atBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->colorList().at(index);
+}
+
+void DeclarativeTheme3D::clearBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearColors();
+}
+
+QQmlListProperty<ColorGradient> DeclarativeTheme3D::baseGradients()
+{
+ return QQmlListProperty<ColorGradient>(this, this,
+ &DeclarativeTheme3D::appendBaseGradientsFunc,
+ &DeclarativeTheme3D::countBaseGradientsFunc,
+ &DeclarativeTheme3D::atBaseGradientsFunc,
+ &DeclarativeTheme3D::clearBaseGradientsFunc);
+}
+
+void DeclarativeTheme3D::appendBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ ColorGradient *gradient)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->addGradient(gradient);
+}
+
+qsizetype DeclarativeTheme3D::countBaseGradientsFunc(QQmlListProperty<ColorGradient> *list)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().size();
+}
+
+ColorGradient *DeclarativeTheme3D::atBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ qsizetype index)
+{
+ return reinterpret_cast<DeclarativeTheme3D *>(list->data)->gradientList().at(index);
+}
+
+void DeclarativeTheme3D::clearBaseGradientsFunc(QQmlListProperty<ColorGradient> *list)
+{
+ reinterpret_cast<DeclarativeTheme3D *>(list->data)->clearGradients();
+}
+
+QT_END_NAMESPACE
diff --git a/src/datavisualizationqml/declarativetheme_p.h b/src/datavisualizationqml/declarativetheme_p.h
new file mode 100644
index 00000000..ea59641d
--- /dev/null
+++ b/src/datavisualizationqml/declarativetheme_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef DECLARATIVETHEME_P_H
+#define DECLARATIVETHEME_P_H
+
+#include <private/datavisualizationglobal_p.h>
+#include <private/q3dtheme_p.h>
+
+#include "declarativecolor_p.h"
+#include "colorgradient_p.h"
+
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlparserstatus.h>
+
+QT_BEGIN_NAMESPACE
+
+class DeclarativeTheme3D : public Q3DTheme, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QQmlListProperty<QObject> themeChildren READ themeChildren)
+ Q_PROPERTY(QQmlListProperty<DeclarativeColor> baseColors READ baseColors)
+ Q_PROPERTY(QQmlListProperty<ColorGradient> baseGradients READ baseGradients)
+ Q_PROPERTY(ColorGradient *singleHighlightGradient READ singleHighlightGradient WRITE setSingleHighlightGradient NOTIFY singleHighlightGradientChanged)
+ Q_PROPERTY(ColorGradient *multiHighlightGradient READ multiHighlightGradient WRITE setMultiHighlightGradient NOTIFY multiHighlightGradientChanged)
+ Q_CLASSINFO("DefaultProperty", "themeChildren")
+ QML_NAMED_ELEMENT(Theme3D)
+ QML_ADDED_IN_VERSION(1, 0)
+
+public:
+ DeclarativeTheme3D(QObject *parent = 0);
+ virtual ~DeclarativeTheme3D();
+
+ QQmlListProperty<QObject> themeChildren();
+ static void appendThemeChildren(QQmlListProperty<QObject> *list, QObject *element);
+
+ QQmlListProperty<DeclarativeColor> baseColors();
+ static void appendBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ DeclarativeColor *color);
+ static qsizetype countBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list);
+ static DeclarativeColor *atBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list,
+ qsizetype index);
+ static void clearBaseColorsFunc(QQmlListProperty<DeclarativeColor> *list);
+
+ QQmlListProperty<ColorGradient> baseGradients();
+ static void appendBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ ColorGradient *gradient);
+ static qsizetype countBaseGradientsFunc(QQmlListProperty<ColorGradient> *list);
+ static ColorGradient *atBaseGradientsFunc(QQmlListProperty<ColorGradient> *list,
+ qsizetype index);
+ static void clearBaseGradientsFunc(QQmlListProperty<ColorGradient> *list);
+
+ void setSingleHighlightGradient(ColorGradient *gradient);
+ ColorGradient *singleHighlightGradient() const;
+
+ void setMultiHighlightGradient(ColorGradient *gradient);
+ ColorGradient *multiHighlightGradient() const;
+
+ // From QQmlParserStatus
+ void classBegin() override;
+ void componentComplete() override;
+
+Q_SIGNALS:
+ void singleHighlightGradientChanged(ColorGradient *gradient);
+ void multiHighlightGradientChanged(ColorGradient *gradient);
+
+protected:
+ void handleTypeChange(Theme themeType);
+ void handleBaseColorUpdate();
+ void handleBaseGradientUpdate();
+ void handleSingleHLGradientUpdate();
+ void handleMultiHLGradientUpdate();
+
+ enum GradientType {
+ GradientTypeBase = 0,
+ GradientTypeSingleHL,
+ GradientTypeMultiHL
+ };
+
+private:
+ void addColor(DeclarativeColor *color);
+ QList<DeclarativeColor *> colorList();
+ void clearColors();
+ void clearDummyColors();
+
+ void addGradient(ColorGradient *gradient);
+ QList<ColorGradient *> gradientList();
+ void clearGradients();
+ void clearDummyGradients();
+
+ void setThemeGradient(ColorGradient *gradient, GradientType type);
+ QLinearGradient convertGradient(ColorGradient *gradient);
+ ColorGradient *convertGradient(const QLinearGradient &gradient);
+
+ QList<DeclarativeColor *> m_colors; // Not owned
+ QList<ColorGradient *> m_gradients; // Not owned
+ ColorGradient *m_singleHLGradient; // Not owned
+ ColorGradient *m_multiHLGradient; // Not owned
+
+ bool m_dummyGradients;
+ bool m_dummyColors;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualizationqml/designer/Bars3DSpecifics.qml b/src/datavisualizationqml/designer/Bars3DSpecifics.qml
new file mode 100644
index 00000000..cd1e76b4
--- /dev/null
+++ b/src/datavisualizationqml/designer/Bars3DSpecifics.qml
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.1 as Controls
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Bars3D")
+
+ SectionLayout {
+ Label {
+ text: qsTr("multiSeriesUniform")
+ tooltip: qsTr("Multiseries Uniform")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.multiSeriesUniform
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("barThickness")
+ tooltip: qsTr("Bar Thickness Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.barThickness
+ minimumValue: 0.01
+ maximumValue: 100.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("barSpacing")
+ tooltip: qsTr("Bar Spacing")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ prefix: "col: "
+ backendValue: backendValues.barSpacing_width
+ minimumValue: 0.0
+ maximumValue: 10.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ SpinBox {
+ prefix: "row: "
+ backendValue: backendValues.barSpacing_height
+ minimumValue: 0.0
+ maximumValue: 10.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("barSpacingRelative")
+ tooltip: qsTr("Bar Spacing Relative")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.barSpacingRelative
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("renderingMode")
+ tooltip: qsTr("Rendering Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.renderingMode
+ model: ["RenderIndirect", "RenderDirectToBackground",
+ "RenderDirectToBackground_NoClear"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("msaaSamples")
+ tooltip: qsTr("MSAA Sample Count")
+ Layout.fillWidth: true
+ }
+ SpinBox {
+ suffix: " x MSAA"
+ backendValue: backendValues.msaaSamples
+ minimumValue: 0
+ maximumValue: 16
+ Layout.fillWidth: true
+ }
+ Label {
+ text: qsTr("shadowQuality")
+ tooltip: qsTr("Shadow Quality")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.shadowQuality
+ model: ["ShadowQualityNone", "ShadowQualityLow", "ShadowQualityMedium",
+ "ShadowQualityHigh", "ShadowQualitySoftLow", "ShadowQualitySoftMedium",
+ "ShadowQualitySoftHigh"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("selectionMode")
+ tooltip: qsTr("Selection Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ id: selectionLayout
+ property bool isInModel: backendValue.isInModel;
+ property bool isInSubState: backendValue.isInSubState;
+ property bool selectionChangedFlag: selectionChanged
+ property variant backendValue: backendValues.selectionMode
+ property variant valueFromBackend: backendValue.value
+ property string enumScope: "AbstractGraph3D"
+ property string enumSeparator: " | "
+ property int checkedCount: 0
+ property bool selectionItem: false
+ property bool selectionRow: false
+ property bool selectionColumn: false
+ property bool selectionSlice: false
+ property bool selectionMulti: false
+
+ function checkValue(checkedVariable, variableText, expressionBase) {
+ var expressionStr = expressionBase
+ if (checkedVariable) {
+ if (expressionStr !== "") {
+ expressionStr += enumSeparator
+ }
+ expressionStr += enumScope
+ expressionStr += "."
+ expressionStr += variableText
+ checkedCount++
+ }
+ return expressionStr
+ }
+
+ function composeSelectionMode() {
+ var expressionStr = ""
+ checkedCount = 0
+ expressionStr = checkValue(selectionItem, "SelectionItem", expressionStr)
+ expressionStr = checkValue(selectionRow, "SelectionRow", expressionStr)
+ expressionStr = checkValue(selectionColumn, "SelectionColumn", expressionStr)
+ expressionStr = checkValue(selectionSlice, "SelectionSlice", expressionStr)
+ expressionStr = checkValue(selectionMulti, "SelectionMultiSeries", expressionStr)
+
+ if (checkedCount === 0)
+ backendValue.expression = enumScope + ".SelectionNone"
+ else
+ backendValue.expression = expressionStr
+ }
+
+ function evaluate() {
+ if (backendValue.value === undefined)
+ return
+
+ selectionItem = (backendValue.expression.indexOf("SelectionItem") !== -1)
+ selectionRow = (backendValue.expression.indexOf("SelectionRow") !== -1)
+ selectionColumn = (backendValue.expression.indexOf("SelectionColumn") !== -1)
+ selectionSlice = (backendValue.expression.indexOf("SelectionSlice") !== -1)
+ selectionMulti = (backendValue.expression.indexOf("SelectionMultiSeries") !== -1)
+
+ selectionItemBox.checked = selectionItem
+ selectionRowBox.checked = selectionRow
+ selectionColumnBox.checked = selectionColumn
+ selectionSliceBox.checked = selectionSlice
+ selectionMultiSeriesBox.checked = selectionMulti
+ }
+
+ onSelectionChangedFlagChanged: evaluate()
+
+ onIsInModelChanged: evaluate()
+
+ onIsInSubStateChanged: evaluate()
+
+ onBackendValueChanged: evaluate()
+
+ onValueFromBackendChanged: evaluate()
+
+ ColumnLayout {
+ anchors.fill: parent
+
+ Controls.CheckBox {
+ id: selectionItemBox
+ style: checkBox.style
+ text: "SelectionItem"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionItem = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionRowBox
+ style: checkBox.style
+ text: "SelectionRow"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionRow = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionColumnBox
+ style: checkBox.style
+ text: "SelectionColumn"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionColumn = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionSliceBox
+ style: checkBox.style
+ text: "SelectionSlice"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionSlice = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionMultiSeriesBox
+ style: checkBox.style
+ text: "SelectionMultiSeries"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionMulti = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ }
+ }
+ Label {
+ text: qsTr("measureFps")
+ tooltip: qsTr("Measure Frames Per Second")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.measureFps
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("orthoProjection")
+ tooltip: qsTr("Use Orthographic Projection")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.orthoProjection
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("aspectRatio")
+ tooltip: qsTr("Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.aspectRatio
+ minimumValue: 0.01
+ maximumValue: 100.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("floorLevel")
+ tooltip: qsTr("Floor Level")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ LineEdit {
+ backendValue: backendValues.floorLevel
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("horizontalAspectRatio")
+ tooltip: qsTr("Horizontal Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.horizontalAspectRatio
+ minimumValue: 0.0
+ maximumValue: 100.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("reflection")
+ tooltip: qsTr("Reflection")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ id: reflectionCheckbox
+ backendValue: backendValues.reflection
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("reflectivity")
+ tooltip: qsTr("Reflectivity")
+ Layout.fillWidth: true
+ visible: reflectionCheckbox.checked
+ }
+ SecondColumnLayout {
+ visible: reflectionCheckbox.checked
+ SpinBox {
+ backendValue: backendValues.reflectivity
+ minimumValue: 0.0
+ maximumValue: 1.0
+ stepSize: 0.01
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("margin")
+ tooltip: qsTr("Graph Margin")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.margin
+ minimumValue: -1.0
+ maximumValue: 100.0
+ stepSize: 0.1
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+
+ // Kept for debugging
+ Label { }
+ SecondColumnLayout {
+ TextEdit {
+ id: debugLabel
+ Layout.fillWidth: true
+ wrapMode: TextEdit.WordWrap
+ textFormat: TextEdit.RichText
+ width: 400
+ visible: false
+ }
+ }
+ Controls.CheckBox {
+ property color textColor: colorLogic.textColor
+ id: checkBox
+ style: CustomCheckBoxStyle {}
+ visible: false
+ ColorLogic {
+ id: colorLogic
+ backendValue: backendValues.selectionMode
+ }
+ }
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/Scatter3DSpecifics.qml b/src/datavisualizationqml/designer/Scatter3DSpecifics.qml
new file mode 100644
index 00000000..b864fb16
--- /dev/null
+++ b/src/datavisualizationqml/designer/Scatter3DSpecifics.qml
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Scatter3D")
+
+ SectionLayout {
+ Label {
+ text: qsTr("renderingMode")
+ tooltip: qsTr("Rendering Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.renderingMode
+ model: ["RenderIndirect", "RenderDirectToBackground",
+ "RenderDirectToBackground_NoClear"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("msaaSamples")
+ tooltip: qsTr("MSAA Sample Count")
+ Layout.fillWidth: true
+ }
+ SpinBox {
+ suffix: " x MSAA"
+ backendValue: backendValues.msaaSamples
+ minimumValue: 0
+ maximumValue: 16
+ Layout.fillWidth: true
+ }
+ Label {
+ text: qsTr("shadowQuality")
+ tooltip: qsTr("Shadow Quality")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.shadowQuality
+ model: ["ShadowQualityNone", "ShadowQualityLow", "ShadowQualityMedium",
+ "ShadowQualityHigh", "ShadowQualitySoftLow", "ShadowQualitySoftMedium",
+ "ShadowQualitySoftHigh"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("selectionMode")
+ tooltip: qsTr("Selection Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.selectionMode
+ model: ["SelectionNone", "SelectionItem"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("measureFps")
+ tooltip: qsTr("Measure Frames Per Second")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.measureFps
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("orthoProjection")
+ tooltip: qsTr("Use Orthographic Projection")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.orthoProjection
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("aspectRatio")
+ tooltip: qsTr("Horizontal to Vertical Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.aspectRatio
+ minimumValue: 0.1
+ maximumValue: 10.0
+ stepSize: 0.1
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("optimizationHints")
+ tooltip: qsTr("Optimization Hints")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.optimizationHints
+ model: ["OptimizationDefault", "OptimizationStatic"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("polar")
+ tooltip: qsTr("Use Polar Coordinates")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ id: polarCheckbox
+ backendValue: backendValues.polar
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("radialLabelOffset")
+ tooltip: qsTr("Radial Label Offset")
+ Layout.fillWidth: true
+ visible: polarCheckbox.checked
+ }
+ SecondColumnLayout {
+ visible: polarCheckbox.checked
+ SpinBox {
+ backendValue: backendValues.radialLabelOffset
+ minimumValue: 0.0
+ maximumValue: 1.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("horizontalAspectRatio")
+ tooltip: qsTr("Horizontal Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.horizontalAspectRatio
+ minimumValue: 0.0
+ maximumValue: 100.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("margin")
+ tooltip: qsTr("Graph Margin")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.margin
+ minimumValue: -1.0
+ maximumValue: 100.0
+ stepSize: 0.1
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/Surface3DSpecifics.qml b/src/datavisualizationqml/designer/Surface3DSpecifics.qml
new file mode 100644
index 00000000..90c2f763
--- /dev/null
+++ b/src/datavisualizationqml/designer/Surface3DSpecifics.qml
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.1 as Controls
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Surface3D")
+
+ SectionLayout {
+ Label {
+ text: qsTr("renderingMode")
+ tooltip: qsTr("Rendering Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.renderingMode
+ model: ["RenderIndirect", "RenderDirectToBackground",
+ "RenderDirectToBackground_NoClear"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("msaaSamples")
+ tooltip: qsTr("MSAA Sample Count")
+ Layout.fillWidth: true
+ }
+ SpinBox {
+ suffix: " x MSAA"
+ backendValue: backendValues.msaaSamples
+ minimumValue: 0
+ maximumValue: 16
+ Layout.fillWidth: true
+ }
+ Label {
+ text: qsTr("shadowQuality")
+ tooltip: qsTr("Shadow Quality")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ ComboBox {
+ backendValue: backendValues.shadowQuality
+ model: ["ShadowQualityNone", "ShadowQualityLow", "ShadowQualityMedium",
+ "ShadowQualityHigh", "ShadowQualitySoftLow", "ShadowQualitySoftMedium",
+ "ShadowQualitySoftHigh"]
+ Layout.fillWidth: true
+ scope: "AbstractGraph3D"
+ }
+ }
+ Label {
+ text: qsTr("selectionMode")
+ tooltip: qsTr("Selection Mode")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ id: selectionLayout
+ property bool isInModel: backendValue.isInModel;
+ property bool isInSubState: backendValue.isInSubState;
+ property bool selectionChangedFlag: selectionChanged
+ property variant backendValue: backendValues.selectionMode
+ property variant valueFromBackend: backendValue.value
+ property string enumScope: "AbstractGraph3D"
+ property string enumSeparator: " | "
+ property int checkedCount: 0
+ property bool selectionItem: false
+ property bool selectionRow: false
+ property bool selectionColumn: false
+ property bool selectionSlice: false
+ property bool selectionMulti: false
+
+ function checkValue(checkedVariable, variableText, expressionBase) {
+ var expressionStr = expressionBase
+ if (checkedVariable) {
+ if (expressionStr !== "") {
+ expressionStr += enumSeparator
+ }
+ expressionStr += enumScope
+ expressionStr += "."
+ expressionStr += variableText
+ checkedCount++
+ }
+ return expressionStr
+ }
+
+ function composeSelectionMode() {
+ var expressionStr = ""
+ checkedCount = 0
+ expressionStr = checkValue(selectionItem, "SelectionItem", expressionStr)
+ expressionStr = checkValue(selectionRow, "SelectionRow", expressionStr)
+ expressionStr = checkValue(selectionColumn, "SelectionColumn", expressionStr)
+ expressionStr = checkValue(selectionSlice, "SelectionSlice", expressionStr)
+ expressionStr = checkValue(selectionMulti, "SelectionMultiSeries", expressionStr)
+
+ if (checkedCount === 0)
+ backendValue.expression = enumScope + ".SelectionNone"
+ else
+ backendValue.expression = expressionStr
+ }
+
+ function evaluate() {
+ if (backendValue.value === undefined)
+ return
+
+ selectionItem = (backendValue.expression.indexOf("SelectionItem") !== -1)
+ selectionRow = (backendValue.expression.indexOf("SelectionRow") !== -1)
+ selectionColumn = (backendValue.expression.indexOf("SelectionColumn") !== -1)
+ selectionSlice = (backendValue.expression.indexOf("SelectionSlice") !== -1)
+ selectionMulti = (backendValue.expression.indexOf("SelectionMultiSeries") !== -1)
+
+ selectionItemBox.checked = selectionItem
+ selectionRowBox.checked = selectionRow
+ selectionColumnBox.checked = selectionColumn
+ selectionSliceBox.checked = selectionSlice
+ selectionMultiSeriesBox.checked = selectionMulti
+ }
+
+ onSelectionChangedFlagChanged: evaluate()
+
+ onIsInModelChanged: evaluate()
+
+ onIsInSubStateChanged: evaluate()
+
+ onBackendValueChanged: evaluate()
+
+ onValueFromBackendChanged: evaluate()
+
+ ColumnLayout {
+ anchors.fill: parent
+
+ Controls.CheckBox {
+ id: selectionItemBox
+ style: checkBox.style
+ text: "SelectionItem"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionItem = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionRowBox
+ style: checkBox.style
+ text: "SelectionRow"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionRow = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionColumnBox
+ style: checkBox.style
+ text: "SelectionColumn"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionColumn = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionSliceBox
+ style: checkBox.style
+ text: "SelectionSlice"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionSlice = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ Controls.CheckBox {
+ id: selectionMultiSeriesBox
+ style: checkBox.style
+ text: "SelectionMultiSeries"
+ Layout.fillWidth: true
+ onClicked: {
+ selectionLayout.selectionMulti = checked
+ selectionLayout.composeSelectionMode()
+ }
+ }
+ }
+ }
+ Label {
+ text: qsTr("measureFps")
+ tooltip: qsTr("Measure Frames Per Second")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.measureFps
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("orthoProjection")
+ tooltip: qsTr("Use Orthographic Projection")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.orthoProjection
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("aspectRatio")
+ tooltip: qsTr("Horizontal to Vertical Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.aspectRatio
+ minimumValue: 0.1
+ maximumValue: 10.0
+ stepSize: 0.1
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("flipHorizontalGrid")
+ tooltip: qsTr("Flip Horizontal Grid")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.flipHorizontalGrid
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("polar")
+ tooltip: qsTr("Use Polar Coordinates")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ CheckBox {
+ id: polarCheckbox
+ backendValue: backendValues.polar
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("radialLabelOffset")
+ tooltip: qsTr("Radial Label Offset")
+ Layout.fillWidth: true
+ visible: polarCheckbox.checked
+ }
+ SecondColumnLayout {
+ visible: polarCheckbox.checked
+ SpinBox {
+ backendValue: backendValues.radialLabelOffset
+ minimumValue: 0.0
+ maximumValue: 1.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("horizontalAspectRatio")
+ tooltip: qsTr("Horizontal Aspect Ratio")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.horizontalAspectRatio
+ minimumValue: 0.0
+ maximumValue: 100.0
+ stepSize: 0.01
+ decimals: 2
+ Layout.fillWidth: true
+ }
+ }
+ Label {
+ text: qsTr("margin")
+ tooltip: qsTr("Graph Margin")
+ Layout.fillWidth: true
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.margin
+ minimumValue: -1.0
+ maximumValue: 100.0
+ stepSize: 0.1
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+
+ // Kept for debugging
+ Label { }
+ SecondColumnLayout {
+ TextEdit {
+ id: debugLabel
+ Layout.fillWidth: true
+ wrapMode: TextEdit.WordWrap
+ textFormat: TextEdit.RichText
+ width: 400
+ visible: false
+ }
+ }
+ Controls.CheckBox {
+ property color textColor: colorLogic.textColor
+ id: checkBox
+ style: CustomCheckBoxStyle {}
+ visible: false
+ ColorLogic {
+ id: colorLogic
+ backendValue: backendValues.selectionMode
+ }
+ }
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/default/Bars3D.qml b/src/datavisualizationqml/designer/default/Bars3D.qml
new file mode 100644
index 00000000..32f4c939
--- /dev/null
+++ b/src/datavisualizationqml/designer/default/Bars3D.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import QtDataVisualization 1.2
+
+Bars3D {
+ width: 300
+ height: 300
+ Bar3DSeries {
+ ItemModelBarDataProxy {
+ itemModel: ListModel {
+ ListElement{ row: "row 1"; column: "column 1"; value: "1"; }
+ ListElement{ row: "row 1"; column: "column 2"; value: "2"; }
+ ListElement{ row: "row 1"; column: "column 3"; value: "3"; }
+ }
+
+ rowRole: "row"
+ columnRole: "column"
+ valueRole: "value"
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/default/Scatter3D.qml b/src/datavisualizationqml/designer/default/Scatter3D.qml
new file mode 100644
index 00000000..2c92d192
--- /dev/null
+++ b/src/datavisualizationqml/designer/default/Scatter3D.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import QtDataVisualization 1.2
+
+Scatter3D {
+ width: 300
+ height: 300
+ Scatter3DSeries {
+ ItemModelScatterDataProxy {
+ itemModel: ListModel {
+ ListElement{ x: "1"; y: "2"; z: "3"; }
+ ListElement{ x: "2"; y: "3"; z: "4"; }
+ ListElement{ x: "3"; y: "4"; z: "1"; }
+ }
+
+ xPosRole: "x"
+ yPosRole: "y"
+ zPosRole: "z"
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/default/Surface3D.qml b/src/datavisualizationqml/designer/default/Surface3D.qml
new file mode 100644
index 00000000..66fd10fb
--- /dev/null
+++ b/src/datavisualizationqml/designer/default/Surface3D.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 2.0
+import QtDataVisualization 1.2
+
+Surface3D {
+ width: 300
+ height: 300
+ Surface3DSeries {
+ ItemModelSurfaceDataProxy {
+ itemModel: ListModel {
+ ListElement{ row: "1"; column: "1"; y: "1"; }
+ ListElement{ row: "1"; column: "2"; y: "2"; }
+ ListElement{ row: "2"; column: "1"; y: "3"; }
+ ListElement{ row: "2"; column: "2"; y: "4"; }
+ }
+
+ rowRole: "row"
+ columnRole: "column"
+ yPosRole: "y"
+ }
+ }
+}
diff --git a/src/datavisualizationqml/designer/images/bars3d-icon.png b/src/datavisualizationqml/designer/images/bars3d-icon.png
new file mode 100644
index 00000000..7f380789
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/bars3d-icon.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/images/bars3d-icon16.png b/src/datavisualizationqml/designer/images/bars3d-icon16.png
new file mode 100644
index 00000000..e85ff502
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/bars3d-icon16.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/images/scatter3d-icon.png b/src/datavisualizationqml/designer/images/scatter3d-icon.png
new file mode 100644
index 00000000..e1ac5c1f
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/scatter3d-icon.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/images/scatter3d-icon16.png b/src/datavisualizationqml/designer/images/scatter3d-icon16.png
new file mode 100644
index 00000000..75b2db18
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/scatter3d-icon16.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/images/surface3d-icon.png b/src/datavisualizationqml/designer/images/surface3d-icon.png
new file mode 100644
index 00000000..956c675e
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/surface3d-icon.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/images/surface3d-icon16.png b/src/datavisualizationqml/designer/images/surface3d-icon16.png
new file mode 100644
index 00000000..6caa643e
--- /dev/null
+++ b/src/datavisualizationqml/designer/images/surface3d-icon16.png
Binary files differ
diff --git a/src/datavisualizationqml/designer/qtdatavisualization.metainfo b/src/datavisualizationqml/designer/qtdatavisualization.metainfo
new file mode 100644
index 00000000..60b2b2c2
--- /dev/null
+++ b/src/datavisualizationqml/designer/qtdatavisualization.metainfo
@@ -0,0 +1,44 @@
+MetaInfo {
+ Type {
+ name: "QtDataVisualization.Bars3D"
+ icon: "images/bars3d-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Bars3D"
+ category: "Qt Data Visualization"
+ libraryIcon: "images/bars3d-icon.png"
+ version: "1.0"
+ requiredImport: "QtDataVisualization"
+
+ QmlSource { source: "default/Bars3D.qml" }
+ }
+ }
+ Type {
+ name: "QtDataVisualization.Scatter3D"
+ icon: "images/scatter3d-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Scatter3D"
+ category: "Qt Data Visualization"
+ libraryIcon: "images/scatter3d-icon.png"
+ version: "1.0"
+ requiredImport: "QtDataVisualization"
+
+ QmlSource { source: "default/Scatter3D.qml" }
+ }
+ }
+ Type {
+ name: "QtDataVisualization.Surface3D"
+ icon: "images/surface3d-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Surface3D"
+ category: "Qt Data Visualization"
+ libraryIcon: "images/surface3d-icon.png"
+ version: "1.0"
+ requiredImport: "QtDataVisualization"
+
+ QmlSource { source: "default/Surface3D.qml" }
+ }
+ }
+}
diff --git a/src/datavisualizationqml/enumtostringmap.cpp b/src/datavisualizationqml/enumtostringmap.cpp
new file mode 100644
index 00000000..e10e8bc0
--- /dev/null
+++ b/src/datavisualizationqml/enumtostringmap.cpp
@@ -0,0 +1,413 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "enumtostringmap_p.h"
+
+#ifdef VERBOSE_STATE_STORE
+
+#include <QDebug>
+
+static EnumToStringMap *theInstance = 0;
+static unsigned int theInstanceCount = 0;
+
+EnumToStringMap *EnumToStringMap::newInstance()
+{
+ if (theInstance) {
+ theInstanceCount++;
+ return theInstance;
+ }
+
+ theInstance = new EnumToStringMap();
+ theInstanceCount++;
+ return theInstance;
+}
+
+void EnumToStringMap::deleteInstance()
+{
+ theInstanceCount--;
+ if (theInstanceCount <= 0) {
+ delete theInstance;
+ theInstance = 0;
+ }
+}
+
+EnumToStringMap::EnumToStringMap() :
+ m_unknown("<unknown>")
+{
+ m_map[GL_ZERO] = "ZERO/null";
+
+ m_map[GL_DEPTH_BUFFER_BIT] = "DEPTH_BUFFER_BIT";
+ m_map[GL_STENCIL_BUFFER_BIT] = "STENCIL_BUFFER_BIT";
+ m_map[GL_COLOR_BUFFER_BIT] = "COLOR_BUFFER_BIT";
+
+ m_map[GL_STENCIL_BUFFER_BIT] = "STENCIL_BUFFER_BIT";
+ m_map[GL_COLOR_BUFFER_BIT] = "COLOR_BUFFER_BIT";
+
+ m_map[GL_POINTS] = "POINTS";
+ m_map[GL_LINES] = "LINES";
+ m_map[GL_LINE_LOOP] = "LINE_LOOP";
+ m_map[GL_LINE_STRIP] = "LINE_STRIP";
+ m_map[GL_TRIANGLES] = "TRIANGLES";
+ m_map[GL_TRIANGLE_STRIP] = "TRIANGLE_STRIP";
+ m_map[GL_TRIANGLE_FAN] = "TRIANGLE_FAN";
+
+ m_map[GL_SRC_COLOR] = "SRC_COLOR";
+ m_map[GL_ONE_MINUS_SRC_COLOR] = "ONE_MINUS_SRC_COLOR";
+ m_map[GL_SRC_ALPHA] = "SRC_ALPHA";
+ m_map[GL_ONE_MINUS_SRC_ALPHA] = "ONE_MINUS_SRC_ALPHA";
+ m_map[GL_DST_ALPHA] = "DST_ALPHA";
+ m_map[GL_ONE_MINUS_DST_ALPHA] = "ONE_MINUS_DST_ALPHA";
+
+ m_map[GL_DST_COLOR] = "DST_COLOR";
+ m_map[GL_ONE_MINUS_DST_COLOR] = "ONE_MINUS_DST_COLOR";
+ m_map[GL_SRC_ALPHA_SATURATE] = "SRC_ALPHA_SATURATE";
+
+ m_map[GL_FUNC_ADD] = "FUNC_ADD";
+ m_map[GL_BLEND_EQUATION] = "BLEND_EQUATION";
+ m_map[GL_BLEND_EQUATION_RGB] = "BLEND_EQUATION_RGB";
+ m_map[GL_BLEND_EQUATION_ALPHA] = "BLEND_EQUATION_ALPHA";
+
+ m_map[GL_FUNC_SUBTRACT] = "FUNC_SUBTRACT";
+ m_map[GL_FUNC_REVERSE_SUBTRACT] = "FUNC_REVERSE_SUBTRACT";
+
+ m_map[GL_BLEND_DST_RGB] = "BLEND_DST_RGB";
+ m_map[GL_BLEND_SRC_RGB] = "BLEND_SRC_RGB";
+ m_map[GL_BLEND_DST_ALPHA] = "BLEND_DST_ALPHA";
+ m_map[GL_BLEND_SRC_ALPHA] = "BLEND_SRC_ALPHA";
+ m_map[GL_CONSTANT_COLOR] = "CONSTANT_COLOR";
+ m_map[GL_ONE_MINUS_CONSTANT_COLOR] = "ONE_MINUS_CONSTANT_COLOR";
+ m_map[GL_CONSTANT_ALPHA] = "CONSTANT_ALPHA";
+ m_map[GL_ONE_MINUS_CONSTANT_ALPHA] = "ONE_MINUS_CONSTANT_ALPHA";
+ m_map[GL_BLEND_COLOR] = "BLEND_COLOR";
+
+ m_map[GL_ARRAY_BUFFER] = "ARRAY_BUFFER";
+ m_map[GL_ELEMENT_ARRAY_BUFFER] = "ELEMENT_ARRAY_BUFFER";
+ m_map[GL_ARRAY_BUFFER_BINDING] = "ARRAY_BUFFER_BINDING";
+ m_map[GL_ELEMENT_ARRAY_BUFFER_BINDING] = "ELEMENT_ARRAY_BUFFER_BINDING";
+
+ m_map[GL_STREAM_DRAW] = "STREAM_DRAW";
+ m_map[GL_STATIC_DRAW] = "STATIC_DRAW";
+ m_map[GL_DYNAMIC_DRAW] = "DYNAMIC_DRAW";
+
+ m_map[GL_BUFFER_SIZE] = "BUFFER_SIZE";
+ m_map[GL_BUFFER_USAGE] = "BUFFER_USAGE";
+
+ m_map[GL_CURRENT_VERTEX_ATTRIB] = "CURRENT_VERTEX_ATTRIB";
+
+ m_map[GL_FRONT] = "FRONT";
+ m_map[GL_BACK] = "BACK";
+ m_map[GL_FRONT_AND_BACK] = "FRONT_AND_BACK";
+
+ m_map[GL_CULL_FACE] = "CULL_FACE";
+ m_map[GL_BLEND] = "BLEND";
+ m_map[GL_DITHER] = "DITHER";
+ m_map[GL_STENCIL_TEST] = "STENCIL_TEST";
+ m_map[GL_DEPTH_TEST] = "DEPTH_TEST";
+ m_map[GL_SCISSOR_TEST] = "SCISSOR_TEST";
+ m_map[GL_POLYGON_OFFSET_FILL] = "POLYGON_OFFSET_FILL";
+ m_map[GL_SAMPLE_ALPHA_TO_COVERAGE] = "SAMPLE_ALPHA_TO_COVERAGE";
+ m_map[GL_SAMPLE_COVERAGE] = "SAMPLE_COVERAGE";
+
+ m_map[GL_NO_ERROR] = "NO_ERROR";
+ m_map[GL_INVALID_ENUM] = "INVALID_ENUM";
+ m_map[GL_INVALID_VALUE] = "INVALID_VALUE";
+ m_map[GL_INVALID_OPERATION] = "INVALID_OPERATION";
+ m_map[GL_OUT_OF_MEMORY] = "OUT_OF_MEMORY";
+
+ m_map[GL_CW] = "CW";
+ m_map[GL_CCW] = "CCW";
+
+ m_map[GL_LINE_WIDTH] = "LINE_WIDTH";
+ m_map[GL_ALIASED_POINT_SIZE_RANGE] = "ALIASED_POINT_SIZE_RANGE";
+ m_map[GL_ALIASED_LINE_WIDTH_RANGE] = "ALIASED_LINE_WIDTH_RANGE";
+ m_map[GL_CULL_FACE_MODE] = "CULL_FACE_MODE";
+ m_map[GL_FRONT_FACE] = "FRONT_FACE";
+ m_map[GL_DEPTH_RANGE] = "DEPTH_RANGE";
+ m_map[GL_DEPTH_WRITEMASK] = "DEPTH_WRITEMASK";
+ m_map[GL_DEPTH_CLEAR_VALUE] = "DEPTH_CLEAR_VALUE";
+ m_map[GL_DEPTH_FUNC] = "DEPTH_FUNC";
+ m_map[GL_STENCIL_CLEAR_VALUE] = "STENCIL_CLEAR_VALUE";
+ m_map[GL_STENCIL_FUNC] = "STENCIL_FUNC";
+ m_map[GL_STENCIL_FAIL] = "STENCIL_FAIL";
+ m_map[GL_STENCIL_PASS_DEPTH_FAIL] = "STENCIL_PASS_DEPTH_FAIL";
+ m_map[GL_STENCIL_PASS_DEPTH_PASS] = "STENCIL_PASS_DEPTH_PASS";
+ m_map[GL_STENCIL_REF] = "STENCIL_REF";
+ m_map[GL_STENCIL_VALUE_MASK] = "STENCIL_VALUE_MASK";
+ m_map[GL_STENCIL_WRITEMASK] = "STENCIL_WRITEMASK";
+ m_map[GL_STENCIL_BACK_FUNC] = "STENCIL_BACK_FUNC";
+ m_map[GL_STENCIL_BACK_FAIL] = "STENCIL_BACK_FAIL";
+ m_map[GL_STENCIL_BACK_PASS_DEPTH_FAIL] = "STENCIL_BACK_PASS_DEPTH_FAIL";
+ m_map[GL_STENCIL_BACK_PASS_DEPTH_PASS] = "STENCIL_BACK_PASS_DEPTH_PASS";
+ m_map[GL_STENCIL_BACK_REF] = "STENCIL_BACK_REF";
+ m_map[GL_STENCIL_BACK_VALUE_MASK] = "STENCIL_BACK_VALUE_MASK";
+ m_map[GL_STENCIL_BACK_WRITEMASK] = "STENCIL_BACK_WRITEMASK";
+ m_map[GL_VIEWPORT] = "VIEWPORT";
+ m_map[GL_SCISSOR_BOX] = "SCISSOR_BOX";
+
+ m_map[GL_COLOR_CLEAR_VALUE] = "COLOR_CLEAR_VALUE";
+ m_map[GL_COLOR_WRITEMASK] = "COLOR_WRITEMASK";
+ m_map[GL_UNPACK_ALIGNMENT] = "UNPACK_ALIGNMENT";
+ m_map[GL_PACK_ALIGNMENT] = "PACK_ALIGNMENT";
+ m_map[GL_MAX_TEXTURE_SIZE] = "MAX_TEXTURE_SIZE";
+ m_map[GL_MAX_VIEWPORT_DIMS] = "MAX_VIEWPORT_DIMS";
+ m_map[GL_SUBPIXEL_BITS] = "SUBPIXEL_BITS";
+ m_map[GL_RED_BITS] = "RED_BITS";
+ m_map[GL_GREEN_BITS] = "GREEN_BITS";
+ m_map[GL_BLUE_BITS] = "BLUE_BITS";
+ m_map[GL_ALPHA_BITS] = "ALPHA_BITS";
+ m_map[GL_DEPTH_BITS] = "DEPTH_BITS";
+ m_map[GL_STENCIL_BITS] = "STENCIL_BITS";
+ m_map[GL_POLYGON_OFFSET_UNITS] = "POLYGON_OFFSET_UNITS";
+
+ m_map[GL_POLYGON_OFFSET_FACTOR] = "POLYGON_OFFSET_FACTOR";
+ m_map[GL_TEXTURE_BINDING_2D] = "TEXTURE_BINDING_2D";
+ m_map[GL_SAMPLE_BUFFERS] = "SAMPLE_BUFFERS";
+ m_map[GL_SAMPLES] = "SAMPLES";
+ m_map[GL_SAMPLE_COVERAGE_VALUE] = "SAMPLE_COVERAGE_VALUE";
+ m_map[GL_SAMPLE_COVERAGE_INVERT] = "SAMPLE_COVERAGE_INVERT";
+
+ m_map[GL_COMPRESSED_TEXTURE_FORMATS] = "COMPRESSED_TEXTURE_FORMATS";
+
+ m_map[GL_DONT_CARE] = "DONT_CARE";
+ m_map[GL_FASTEST] = "FASTEST";
+ m_map[GL_NICEST] = "NICEST";
+
+ m_map[GL_GENERATE_MIPMAP_HINT] = "GENERATE_MIPMAP_HINT";
+
+ m_map[GL_BYTE] = "BYTE";
+ m_map[GL_UNSIGNED_BYTE] = "UNSIGNED_BYTE";
+ m_map[GL_SHORT] = "SHORT";
+ m_map[GL_UNSIGNED_SHORT] = "UNSIGNED_SHORT";
+ m_map[GL_INT] = "INT";
+ m_map[GL_UNSIGNED_INT] = "UNSIGNED_INT";
+ m_map[GL_FLOAT] = "FLOAT";
+
+ m_map[GL_DEPTH_COMPONENT] = "DEPTH_COMPONENT";
+ m_map[GL_ALPHA] = "ALPHA";
+ m_map[GL_RGB] = "RGB";
+ m_map[GL_RGBA] = "RGBA";
+ m_map[GL_LUMINANCE] = "LUMINANCE";
+ m_map[GL_LUMINANCE_ALPHA] = "LUMINANCE_ALPHA";
+
+ m_map[GL_UNSIGNED_SHORT_4_4_4_4] = "UNSIGNED_SHORT_4_4_4_4";
+ m_map[GL_UNSIGNED_SHORT_5_5_5_1] = "UNSIGNED_SHORT_5_5_5_1";
+ m_map[GL_UNSIGNED_SHORT_5_6_5] = "UNSIGNED_SHORT_5_6_5";
+
+ m_map[GL_FRAGMENT_SHADER] = "FRAGMENT_SHADER";
+ m_map[GL_VERTEX_SHADER] = "VERTEX_SHADER";
+ m_map[GL_MAX_VERTEX_ATTRIBS] = "MAX_VERTEX_ATTRIBS";
+ m_map[GL_MAX_VERTEX_UNIFORM_VECTORS] = "MAX_VERTEX_UNIFORM_VECTORS";
+ m_map[GL_MAX_VARYING_VECTORS] = "MAX_VARYING_VECTORS";
+ m_map[GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS] = "MAX_COMBINED_TEXTURE_IMAGE_UNITS";
+ m_map[GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS] = "MAX_VERTEX_TEXTURE_IMAGE_UNITS";
+ m_map[GL_MAX_TEXTURE_IMAGE_UNITS] = "MAX_TEXTURE_IMAGE_UNITS";
+ m_map[GL_MAX_FRAGMENT_UNIFORM_VECTORS] = "MAX_FRAGMENT_UNIFORM_VECTORS";
+ m_map[GL_SHADER_TYPE] = "SHADER_TYPE";
+ m_map[GL_DELETE_STATUS] = "DELETE_STATUS";
+ m_map[GL_LINK_STATUS] = "LINK_STATUS";
+ m_map[GL_VALIDATE_STATUS] = "VALIDATE_STATUS";
+ m_map[GL_ATTACHED_SHADERS] = "ATTACHED_SHADERS";
+ m_map[GL_ACTIVE_UNIFORMS] = "ACTIVE_UNIFORMS";
+ m_map[GL_ACTIVE_ATTRIBUTES] = "ACTIVE_ATTRIBUTES";
+ m_map[GL_SHADING_LANGUAGE_VERSION] = "SHADING_LANGUAGE_VERSION";
+ m_map[GL_CURRENT_PROGRAM] = "CURRENT_PROGRAM";
+
+ m_map[GL_NEVER] = "NEVER";
+ m_map[GL_LESS] = "LESS";
+ m_map[GL_EQUAL] = "EQUAL";
+ m_map[GL_LEQUAL] = "LEQUAL";
+ m_map[GL_GREATER] = "GREATER";
+ m_map[GL_NOTEQUAL] = "NOTEQUAL";
+ m_map[GL_GEQUAL] = "GEQUAL";
+ m_map[GL_ALWAYS] = "ALWAYS";
+
+ m_map[GL_KEEP] = "KEEP";
+ m_map[GL_REPLACE] = "REPLACE";
+ m_map[GL_INCR] = "INCR";
+ m_map[GL_DECR] = "DECR";
+ m_map[GL_INVERT] = "INVERT";
+ m_map[GL_INCR_WRAP] = "INCR_WRAP";
+ m_map[GL_DECR_WRAP] = "DECR_WRAP";
+
+ m_map[GL_VENDOR] = "VENDOR";
+ m_map[GL_RENDERER] = "RENDERER";
+ m_map[GL_VERSION] = "VERSION";
+
+ m_map[GL_NEAREST] = "NEAREST";
+ m_map[GL_LINEAR] = "LINEAR";
+
+ m_map[GL_NEAREST_MIPMAP_NEAREST] = "NEAREST_MIPMAP_NEAREST";
+ m_map[GL_LINEAR_MIPMAP_NEAREST] = "LINEAR_MIPMAP_NEAREST";
+ m_map[GL_NEAREST_MIPMAP_LINEAR] = "NEAREST_MIPMAP_LINEAR";
+ m_map[GL_LINEAR_MIPMAP_LINEAR] = "LINEAR_MIPMAP_LINEAR";
+
+ m_map[GL_TEXTURE_MAG_FILTER] = "TEXTURE_MAG_FILTER";
+ m_map[GL_TEXTURE_MIN_FILTER] = "TEXTURE_MIN_FILTER";
+ m_map[GL_TEXTURE_WRAP_S] = "TEXTURE_WRAP_S";
+ m_map[GL_TEXTURE_WRAP_T] = "TEXTURE_WRAP_T";
+
+ m_map[GL_TEXTURE_2D] = "TEXTURE_2D";
+ m_map[GL_TEXTURE] = "TEXTURE";
+
+ m_map[GL_TEXTURE_CUBE_MAP] = "TEXTURE_CUBE_MAP";
+ m_map[GL_TEXTURE_BINDING_CUBE_MAP] = "TEXTURE_BINDING_CUBE_MAP";
+ m_map[GL_TEXTURE_CUBE_MAP_POSITIVE_X] = "TEXTURE_CUBE_MAP_POSITIVE_X";
+ m_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_X] = "TEXTURE_CUBE_MAP_NEGATIVE_X";
+ m_map[GL_TEXTURE_CUBE_MAP_POSITIVE_Y] = "TEXTURE_CUBE_MAP_POSITIVE_Y";
+ m_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_Y] = "TEXTURE_CUBE_MAP_NEGATIVE_Y";
+ m_map[GL_TEXTURE_CUBE_MAP_POSITIVE_Z] = "TEXTURE_CUBE_MAP_POSITIVE_Z";
+ m_map[GL_TEXTURE_CUBE_MAP_NEGATIVE_Z] = "TEXTURE_CUBE_MAP_NEGATIVE_Z";
+ m_map[GL_MAX_CUBE_MAP_TEXTURE_SIZE] = "MAX_CUBE_MAP_TEXTURE_SIZE";
+
+ m_map[GL_TEXTURE0] = "TEXTURE0";
+ m_map[GL_TEXTURE1] = "TEXTURE1";
+ m_map[GL_TEXTURE2] = "TEXTURE2";
+ m_map[GL_TEXTURE3] = "TEXTURE3";
+ m_map[GL_TEXTURE4] = "TEXTURE4";
+ m_map[GL_TEXTURE5] = "TEXTURE5";
+ m_map[GL_TEXTURE6] = "TEXTURE6";
+ m_map[GL_TEXTURE7] = "TEXTURE7";
+ m_map[GL_TEXTURE8] = "TEXTURE8";
+ m_map[GL_TEXTURE9] = "TEXTURE9";
+ m_map[GL_TEXTURE10] = "TEXTURE10";
+ m_map[GL_TEXTURE11] = "TEXTURE11";
+ m_map[GL_TEXTURE12] = "TEXTURE12";
+ m_map[GL_TEXTURE13] = "TEXTURE13";
+ m_map[GL_TEXTURE14] = "TEXTURE14";
+ m_map[GL_TEXTURE15] = "TEXTURE15";
+ m_map[GL_TEXTURE16] = "TEXTURE16";
+ m_map[GL_TEXTURE17] = "TEXTURE17";
+ m_map[GL_TEXTURE18] = "TEXTURE18";
+ m_map[GL_TEXTURE19] = "TEXTURE19";
+ m_map[GL_TEXTURE20] = "TEXTURE20";
+ m_map[GL_TEXTURE21] = "TEXTURE21";
+ m_map[GL_TEXTURE22] = "TEXTURE22";
+ m_map[GL_TEXTURE23] = "TEXTURE23";
+ m_map[GL_TEXTURE24] = "TEXTURE24";
+ m_map[GL_TEXTURE25] = "TEXTURE25";
+ m_map[GL_TEXTURE26] = "TEXTURE26";
+ m_map[GL_TEXTURE27] = "TEXTURE27";
+ m_map[GL_TEXTURE28] = "TEXTURE28";
+ m_map[GL_TEXTURE29] = "TEXTURE29";
+ m_map[GL_TEXTURE30] = "TEXTURE30";
+ m_map[GL_TEXTURE31] = "TEXTURE31";
+ m_map[GL_ACTIVE_TEXTURE] = "ACTIVE_TEXTURE";
+
+ m_map[GL_REPEAT] = "REPEAT";
+ m_map[GL_CLAMP_TO_EDGE] = "CLAMP_TO_EDGE";
+ m_map[GL_MIRRORED_REPEAT] = "MIRRORED_REPEAT";
+
+ m_map[GL_FLOAT_VEC2] = "FLOAT_VEC2";
+ m_map[GL_FLOAT_VEC3] = "FLOAT_VEC3";
+ m_map[GL_FLOAT_VEC4] = "FLOAT_VEC4";
+ m_map[GL_INT_VEC2] = "INT_VEC2";
+ m_map[GL_INT_VEC3] = "INT_VEC3";
+ m_map[GL_INT_VEC4] = "INT_VEC4";
+ m_map[GL_BOOL] = "BOOL";
+ m_map[GL_BOOL_VEC2] = "BOOL_VEC2";
+ m_map[GL_BOOL_VEC3] = "BOOL_VEC3";
+ m_map[GL_BOOL_VEC4] = "BOOL_VEC4";
+ m_map[GL_FLOAT_MAT2] = "FLOAT_MAT2";
+ m_map[GL_FLOAT_MAT3] = "FLOAT_MAT3";
+ m_map[GL_FLOAT_MAT4] = "FLOAT_MAT4";
+ m_map[GL_SAMPLER_2D] = "SAMPLER_2D";
+ m_map[GL_SAMPLER_CUBE] = "SAMPLER_CUBE";
+
+ m_map[GL_VERTEX_ATTRIB_ARRAY_ENABLED] = "VERTEX_ATTRIB_ARRAY_ENABLED";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_SIZE] = "VERTEX_ATTRIB_ARRAY_SIZE";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_STRIDE] = "VERTEX_ATTRIB_ARRAY_STRIDE";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_TYPE] = "VERTEX_ATTRIB_ARRAY_TYPE";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_NORMALIZED] = "VERTEX_ATTRIB_ARRAY_NORMALIZED";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_POINTER] = "VERTEX_ATTRIB_ARRAY_POINTER";
+ m_map[GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING] = "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING";
+
+ m_map[GL_COMPILE_STATUS] = "COMPILE_STATUS";
+
+ m_map[GL_LOW_FLOAT] = "LOW_FLOAT";
+ m_map[GL_MEDIUM_FLOAT] = "MEDIUM_FLOAT";
+ m_map[GL_HIGH_FLOAT] = "HIGH_FLOAT";
+ m_map[GL_LOW_INT] = "LOW_INT";
+ m_map[GL_MEDIUM_INT] = "MEDIUM_INT";
+ m_map[GL_HIGH_INT] = "HIGH_INT";
+
+ m_map[GL_FRAMEBUFFER] = "FRAMEBUFFER";
+ m_map[GL_RENDERBUFFER] = "RENDERBUFFER";
+
+ m_map[GL_RGBA4] = "RGBA4";
+ m_map[GL_RGB5_A1] = "RGB5_A1";
+ m_map[GL_RGB565] = "RGB565";
+ m_map[GL_DEPTH_COMPONENT16] = "DEPTH_COMPONENT16";
+ m_map[GL_STENCIL_INDEX] = "STENCIL_INDEX";
+ m_map[GL_STENCIL_INDEX8] = "STENCIL_INDEX8";
+
+ m_map[GL_RENDERBUFFER_WIDTH] = "RENDERBUFFER_WIDTH";
+ m_map[GL_RENDERBUFFER_HEIGHT] = "RENDERBUFFER_HEIGHT";
+ m_map[GL_RENDERBUFFER_INTERNAL_FORMAT] = "RENDERBUFFER_INTERNAL_FORMAT";
+ m_map[GL_RENDERBUFFER_RED_SIZE] = "RENDERBUFFER_RED_SIZE";
+ m_map[GL_RENDERBUFFER_GREEN_SIZE] = "RENDERBUFFER_GREEN_SIZE";
+ m_map[GL_RENDERBUFFER_BLUE_SIZE] = "RENDERBUFFER_BLUE_SIZE";
+ m_map[GL_RENDERBUFFER_ALPHA_SIZE] = "RENDERBUFFER_ALPHA_SIZE";
+ m_map[GL_RENDERBUFFER_DEPTH_SIZE] = "RENDERBUFFER_DEPTH_SIZE";
+ m_map[GL_RENDERBUFFER_STENCIL_SIZE] = "RENDERBUFFER_STENCIL_SIZE";
+
+ m_map[GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE] = "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE";
+ m_map[GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME] = "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME";
+ m_map[GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL";
+ m_map[GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE] =
+ "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE";
+
+ m_map[GL_COLOR_ATTACHMENT0] = "COLOR_ATTACHMENT0";
+ m_map[GL_DEPTH_ATTACHMENT] = "DEPTH_ATTACHMENT";
+ m_map[GL_STENCIL_ATTACHMENT] = "STENCIL_ATTACHMENT";
+
+ m_map[GL_FRAMEBUFFER_COMPLETE] = "FRAMEBUFFER_COMPLETE";
+ m_map[GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT] = "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
+ m_map[GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT] =
+ "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
+ m_map[GL_FRAMEBUFFER_UNSUPPORTED] = "FRAMEBUFFER_UNSUPPORTED";
+
+ m_map[GL_FRAMEBUFFER_BINDING] = "FRAMEBUFFER_BINDING";
+#if !QT_CONFIG(opengles2)
+ m_map[GL_RENDERBUFFER_BINDING] = "RENDERBUFFER_BINDING";
+#else
+ m_map[GL_RENDERBUFFER] = "RENDERBUFFER_BINDING";
+#endif
+ m_map[GL_MAX_RENDERBUFFER_SIZE] = "MAX_RENDERBUFFER_SIZE";
+
+ m_map[GL_INVALID_FRAMEBUFFER_OPERATION] = "INVALID_FRAMEBUFFER_OPERATION";
+}
+
+QString EnumToStringMap::lookUp(const GLuint value) const
+{
+ if (m_map.contains(value))
+ return m_map[value];
+
+ return QString("0x0%1").arg(value, 0, 16);
+}
+#endif
diff --git a/src/datavisualizationqml/enumtostringmap_p.h b/src/datavisualizationqml/enumtostringmap_p.h
new file mode 100644
index 00000000..ee613433
--- /dev/null
+++ b/src/datavisualizationqml/enumtostringmap_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef ENUMTOSTRINGMAP_P_H
+#define ENUMTOSTRINGMAP_P_H
+
+//#define VERBOSE_STATE_STORE
+
+#ifdef VERBOSE_STATE_STORE
+
+#include <QtGui/qopengl.h>
+#include <QMap>
+#include <QString>
+
+class EnumToStringMap
+{
+public:
+ static EnumToStringMap *newInstance();
+ static void deleteInstance();
+ QString lookUp(const GLuint value) const;
+
+private:
+ EnumToStringMap();
+ QMap<int, QString> m_map;
+ QString m_unknown;
+};
+#endif
+#endif
diff --git a/src/datavisualizationqml/foreigntypes_p.h b/src/datavisualizationqml/foreigntypes_p.h
new file mode 100644
index 00000000..9bf9b1c7
--- /dev/null
+++ b/src/datavisualizationqml/foreigntypes_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef FOREIGNTYPES_P_H
+#define FOREIGNTYPES_P_H
+
+#include <QtQml/qqml.h>
+
+#include <QtCore/qabstractitemmodel.h>
+
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/q3dinputhandler.h>
+#include <QtDataVisualization/q3dlight.h>
+#include <QtDataVisualization/q3dobject.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtDataVisualization/qabstract3daxis.h>
+#include <QtDataVisualization/qabstract3dinputhandler.h>
+#include <QtDataVisualization/qabstract3dseries.h>
+#include <QtDataVisualization/qabstractdataproxy.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/qcategory3daxis.h>
+#include <QtDataVisualization/qcustom3ditem.h>
+#include <QtDataVisualization/qcustom3dlabel.h>
+#include <QtDataVisualization/qcustom3dvolume.h>
+#include <QtDataVisualization/qheightmapsurfacedataproxy.h>
+#include <QtDataVisualization/qitemmodelbardataproxy.h>
+#include <QtDataVisualization/qitemmodelscatterdataproxy.h>
+#include <QtDataVisualization/qitemmodelsurfacedataproxy.h>
+#include <QtDataVisualization/qlogvalue3daxisformatter.h>
+#include <QtDataVisualization/qscatter3dseries.h>
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/qsurface3dseries.h>
+#include <QtDataVisualization/qsurfacedataproxy.h>
+#include <QtDataVisualization/qtouch3dinputhandler.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/qvalue3daxisformatter.h>
+
+QT_BEGIN_NAMESPACE
+
+#define DEFINE_FOREIGN_BASE_ATTRIBUTES(type, name, minor) \
+ Q_GADGET \
+ QML_NAMED_ELEMENT(name) \
+ QML_FOREIGN(type) \
+ QML_ADDED_IN_VERSION(1, minor) \
+
+#define DEFINE_FOREIGN_UNCREATABLE_TYPE(type, name) \
+ struct type##Foreign \
+ { \
+ DEFINE_FOREIGN_BASE_ATTRIBUTES(type, name, 0) \
+ QML_UNCREATABLE("Trying to create uncreatable: " #name ".") \
+ };
+
+#define DEFINE_FOREIGN_CREATABLE_TYPE(type, name, minor) \
+ struct type##Foreign \
+ { \
+ DEFINE_FOREIGN_BASE_ATTRIBUTES(type, name, minor) \
+ };
+
+#define DEFINE_FOREIGN_REPLACED_TYPE(type, name, better) \
+ struct type##Foreign \
+ { \
+ DEFINE_FOREIGN_BASE_ATTRIBUTES(type, name, 0) \
+ QML_UNCREATABLE("Trying to create uncreatable: " #name ", use " #better " instead.") \
+ };
+
+struct Q3DSceneForeign
+{
+ Q_GADGET
+ QML_ANONYMOUS
+ QML_ADDED_IN_VERSION(1, 0)
+ QML_FOREIGN(Q3DScene)
+};
+
+DEFINE_FOREIGN_CREATABLE_TYPE(Q3DCamera, Camera3D, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(Q3DLight, Light3D, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QCategory3DAxis, CategoryAxis3D, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QHeightMapSurfaceDataProxy, HeightMapSurfaceDataProxy, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QItemModelBarDataProxy, ItemModelBarDataProxy, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QItemModelScatterDataProxy, ItemModelScatterDataProxy, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QItemModelSurfaceDataProxy, ItemModelSurfaceDataProxy, 0)
+DEFINE_FOREIGN_CREATABLE_TYPE(QValue3DAxis, ValueAxis3D, 0)
+
+DEFINE_FOREIGN_CREATABLE_TYPE(QCustom3DItem, Custom3DItem, 1)
+DEFINE_FOREIGN_CREATABLE_TYPE(QCustom3DLabel, Custom3DLabel, 1)
+DEFINE_FOREIGN_CREATABLE_TYPE(QLogValue3DAxisFormatter, LogValueAxis3DFormatter, 1)
+DEFINE_FOREIGN_CREATABLE_TYPE(QValue3DAxisFormatter, ValueAxis3DFormatter, 1)
+
+DEFINE_FOREIGN_CREATABLE_TYPE(Q3DInputHandler, InputHandler3D, 2)
+DEFINE_FOREIGN_CREATABLE_TYPE(QCustom3DVolume, Custom3DVolume, 2)
+DEFINE_FOREIGN_CREATABLE_TYPE(QTouch3DInputHandler, TouchInputHandler3D, 2)
+
+DEFINE_FOREIGN_REPLACED_TYPE(Q3DTheme, Q3DTheme, Theme3D)
+DEFINE_FOREIGN_REPLACED_TYPE(QBar3DSeries, QBar3DSeries, Bar3DSeries)
+DEFINE_FOREIGN_REPLACED_TYPE(QScatter3DSeries, QScatter3DSeries, Scatter3DSeries)
+DEFINE_FOREIGN_REPLACED_TYPE(QSurface3DSeries, QSurface3DSeries, Surface3DSeries)
+
+DEFINE_FOREIGN_UNCREATABLE_TYPE(Q3DObject, Object3D)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QAbstract3DAxis, AbstractAxis3D)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QAbstract3DInputHandler, AbstractInputHandler3D)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QAbstract3DSeries, Abstract3DSeries)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QAbstractDataProxy, AbstractDataProxy)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QAbstractItemModel, AbstractItemModel)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QBarDataProxy, BarDataProxy)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QScatterDataProxy, ScatterDataProxy)
+DEFINE_FOREIGN_UNCREATABLE_TYPE(QSurfaceDataProxy, SurfaceDataProxy)
+
+QT_END_NAMESPACE
+
+#endif // FOREIGNTYPES_P_H
diff --git a/src/datavisualizationqml/glstatestore.cpp b/src/datavisualizationqml/glstatestore.cpp
new file mode 100644
index 00000000..dfb4266f
--- /dev/null
+++ b/src/datavisualizationqml/glstatestore.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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 "glstatestore_p.h"
+#include <QDebug>
+#include <QColor>
+#include <QFile>
+
+#ifdef VERBOSE_STATE_STORE
+static QFile *beforeFile = 0;
+static QFile *afterFile = 0;
+#endif
+
+GLStateStore::GLStateStore(QOpenGLContext *context, QObject *parent) :
+ QObject(parent),
+ QOpenGLFunctions(context)
+ #ifdef VERBOSE_STATE_STORE
+ , m_map(EnumToStringMap::newInstance())
+ #endif
+{
+ GLint maxVertexAttribs;
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
+
+#ifdef VERBOSE_STATE_STORE
+ qDebug() << "GL_MAX_VERTEX_ATTRIBS: " << maxVertexAttribs;
+ if (!beforeFile) {
+ beforeFile = new QFile(QStringLiteral("state_before.txt"));
+ afterFile = new QFile(QStringLiteral("state_after.txt"));
+ beforeFile->open(QIODevice::WriteOnly);
+ afterFile->open(QIODevice::WriteOnly);
+ QDebug beforeInit(beforeFile);
+ QDebug afterInit(afterFile);
+ beforeInit << "GL states before 'context switch'" << endl;
+ afterInit << "GL states after 'context switch'" << endl;
+ }
+#endif
+
+ m_maxVertexAttribs = qMin(maxVertexAttribs, 2); // Datavis only uses 2 attribs max
+ m_vertexAttribArrayEnabledStates.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArrayBoundBuffers.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArraySizes.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArrayTypes.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArrayNormalized.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArrayStrides.reset(new GLint[maxVertexAttribs]);
+ m_vertexAttribArrayOffsets.reset(new void *[maxVertexAttribs]);
+
+ initGLDefaultState();
+}
+
+GLStateStore::~GLStateStore()
+{
+#ifdef VERBOSE_STATE_STORE
+ EnumToStringMap::deleteInstance();
+ m_map = 0;
+#endif
+}
+
+void GLStateStore::storeGLState()
+{
+#ifdef VERBOSE_STATE_STORE
+ printCurrentState(true);
+#endif
+
+#if !QT_CONFIG(opengles2)
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &m_drawFramebuffer);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &m_readFramebuffer);
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &m_renderbuffer);
+#endif
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, m_clearColor);
+ m_isBlendingEnabled = glIsEnabled(GL_BLEND);
+ m_isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &m_isDepthWriteEnabled);
+ glGetFloatv(GL_DEPTH_CLEAR_VALUE, &m_clearDepth);
+ glGetIntegerv(GL_DEPTH_FUNC, &m_depthFunc);
+ glGetBooleanv(GL_POLYGON_OFFSET_FILL, &m_polygonOffsetFillEnabled);
+ glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &m_polygonOffsetFactor);
+ glGetFloatv(GL_POLYGON_OFFSET_UNITS, &m_polygonOffsetUnits);
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &m_currentProgram);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &m_activeTexture);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_texBinding2D);
+ glGetIntegerv(GL_FRONT_FACE, &m_frontFace);
+ m_isCullFaceEnabled = glIsEnabled(GL_CULL_FACE);
+ glGetIntegerv(GL_CULL_FACE_MODE, &m_cullFaceMode);
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &m_blendEquationRGB);
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &m_blendEquationAlpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &m_blendDestAlpha);
+ glGetIntegerv(GL_BLEND_DST_RGB, &m_blendDestRGB);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &m_blendSrcAlpha);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &m_blendSrcRGB);
+ glGetIntegerv(GL_SCISSOR_BOX, m_scissorBox);
+ m_isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_boundArrayBuffer);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &m_boundElementArrayBuffer);
+
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED,
+ &m_vertexAttribArrayEnabledStates[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+ &m_vertexAttribArrayBoundBuffers[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &m_vertexAttribArraySizes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &m_vertexAttribArrayTypes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED,
+ &m_vertexAttribArrayNormalized[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &m_vertexAttribArrayStrides[i]);
+ }
+}
+
+#ifdef VERBOSE_STATE_STORE
+void GLStateStore::printCurrentState(bool in)
+{
+ QFile *file;
+ if (in)
+ file = beforeFile;
+ else
+ file = afterFile;
+
+ if (file->isOpen()) {
+ QDebug msg(file);
+#if !QT_CONFIG(opengles2)
+ GLint drawFramebuffer;
+ GLint readFramebuffer;
+ GLint renderbuffer;
+#endif
+ GLfloat clearColor[4];
+ GLfloat clearDepth;
+ GLboolean isBlendingEnabled = glIsEnabled(GL_BLEND);
+ GLboolean isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
+ GLint depthFunc;
+ GLboolean isDepthWriteEnabled;
+ GLint currentProgram;
+ GLint *vertexAttribArrayEnabledStates = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayBoundBuffers = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArraySizes = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayTypes = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayNormalized = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayStrides = new GLint[m_maxVertexAttribs];
+ GLint activeTexture;
+ GLint texBinding2D;
+ GLint arrayBufferBinding;
+ GLint frontFace;
+ GLboolean isCullFaceEnabled = glIsEnabled(GL_CULL_FACE);
+ GLint cullFaceMode;
+ GLint blendEquationRGB;
+ GLint blendEquationAlpha;
+
+ GLint blendDestAlpha;
+ GLint blendDestRGB;
+ GLint blendSrcAlpha;
+ GLint blendSrcRGB;
+ GLint scissorBox[4];
+ GLboolean isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+ GLint boundElementArrayBuffer;
+ GLboolean polygonOffsetFillEnabled;
+ GLfloat polygonOffsetFactor;
+ GLfloat polygonOffsetUnits;
+
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthWriteEnabled);
+#if !QT_CONFIG(opengles2)
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFramebuffer);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFramebuffer);
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &renderbuffer);
+#endif
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
+ glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
+ glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
+ glGetBooleanv(GL_POLYGON_OFFSET_FILL, &polygonOffsetFillEnabled);
+ glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygonOffsetFactor);
+ glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygonOffsetUnits);
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &texBinding2D );
+ glGetIntegerv(GL_FRONT_FACE, &frontFace);
+ glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode);
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
+ glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
+ glGetIntegerv(GL_SCISSOR_BOX, scissorBox);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding);
+
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED,
+ &vertexAttribArrayEnabledStates[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+ &vertexAttribArrayBoundBuffers[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertexAttribArraySizes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertexAttribArrayTypes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED,
+ &vertexAttribArrayNormalized[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertexAttribArrayStrides[i]);
+ }
+
+ QColor color;
+ color.setRgbF(clearColor[0], clearColor[1], clearColor[2]);
+ color.setAlphaF(clearColor[3]);
+
+#if !QT_CONFIG(opengles2)
+ msg << "---" << endl;
+ msg << " GL_DRAW_FRAMEBUFFER_BINDING "<< drawFramebuffer << endl;
+ msg << " GL_READ_FRAMEBUFFER_BINDING "<< readFramebuffer << endl;
+ msg << " GL_RENDERBUFFER_BINDING " << renderbuffer << endl;
+#endif
+ msg << " GL_SCISSOR_TEST " << bool(isScissorTestEnabled) << endl;
+ msg << " GL_SCISSOR_BOX " << m_scissorBox[0] << m_scissorBox[1] << m_scissorBox[2]
+ << m_scissorBox[3] << endl;
+ msg << " GL_COLOR_CLEAR_VALUE "<< color << endl;
+ msg << " GL_DEPTH_CLEAR_VALUE "<< clearDepth << endl;
+ msg << " GL_BLEND "<< bool(isBlendingEnabled) << endl;
+ msg << " GL_BLEND_EQUATION_RGB" << m_map->lookUp(blendEquationRGB) << endl;
+ msg << " GL_BLEND_EQUATION_ALPHA" << m_map->lookUp(blendEquationAlpha) << endl;
+ msg << " GL_BLEND_DST_ALPHA" << m_map->lookUp(blendDestAlpha) << endl;
+ msg << " GL_BLEND_DST_RGB" << m_map->lookUp(blendDestRGB) << endl;
+ msg << " GL_BLEND_SRC_ALPHA" << m_map->lookUp(blendSrcAlpha) << endl;
+ msg << " GL_BLEND_SRC_RGB" << m_map->lookUp(blendSrcRGB) << endl;
+ msg << " GL_DEPTH_TEST "<< bool(isDepthTestEnabled) << endl;
+ msg << " GL_DEPTH_WRITEMASK "<< bool(isDepthWriteEnabled) << endl;
+ msg << " GL_POLYGON_OFFSET_FILL" << bool(polygonOffsetFillEnabled) << endl;
+ msg << " GL_POLYGON_OFFSET_FACTOR "<< polygonOffsetFactor << endl;
+ msg << " GL_POLYGON_OFFSET_UNITS "<< polygonOffsetUnits << endl;
+ msg << " GL_CULL_FACE "<< bool(isCullFaceEnabled) << endl;
+ msg << " GL_CULL_FACE_MODE "<< m_map->lookUp(cullFaceMode) << endl;
+ msg << " GL_DEPTH_FUNC "<< m_map->lookUp(depthFunc) << endl;
+ msg << " GL_FRONT_FACE "<< m_map->lookUp(frontFace) << endl;
+ msg << " GL_CURRENT_PROGRAM "<< currentProgram << endl;
+ msg << " GL_ACTIVE_TEXTURE "<< QString("0x%1").arg(activeTexture, 0, 16) << endl;
+ msg << " GL_TEXTURE_BINDING_2D "<< texBinding2D << endl;
+ msg << " GL_ELEMENT_ARRAY_BUFFER_BINDING "<< boundElementArrayBuffer << endl;
+ msg << " GL_ARRAY_BUFFER_BINDING "<< arrayBufferBinding << endl;
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ msg << " GL_VERTEX_ATTRIB_ARRAY_ENABLED "<< i << " = "
+ << bool(vertexAttribArrayEnabledStates[i]) << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"<< i << " = "
+ << vertexAttribArrayBoundBuffers[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_SIZE"<< i << " = "
+ << vertexAttribArraySizes[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_TYPE"<< i << " = "
+ << vertexAttribArrayTypes[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_NORMALIZED"<< i << " = "
+ << vertexAttribArrayNormalized[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_STRIDE"<< i << " = "
+ << vertexAttribArrayStrides[i] << endl;
+ }
+ }
+}
+#endif
+
+void GLStateStore::restoreGLState()
+{
+#if !QT_CONFIG(opengles2)
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER_BINDING, m_renderbuffer);
+#endif
+
+ if (m_isScissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+ else
+ glDisable(GL_SCISSOR_TEST);
+
+ glScissor(m_scissorBox[0], m_scissorBox[1], m_scissorBox[2], m_scissorBox[3]);
+ glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
+ glClearDepthf(m_clearDepth);
+ if (m_isBlendingEnabled)
+ glEnable(GL_BLEND);
+ else
+ glDisable(GL_BLEND);
+
+ if (m_isDepthTestEnabled)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
+
+ if (m_isCullFaceEnabled)
+ glEnable(GL_CULL_FACE);
+ else
+ glDisable(GL_CULL_FACE);
+
+ glCullFace(m_cullFaceMode);
+
+ glBlendEquationSeparate(m_blendEquationRGB, m_blendEquationAlpha);
+ glBlendFuncSeparate(m_blendSrcRGB, m_blendDestRGB, m_blendSrcAlpha, m_blendDestAlpha);
+
+ glDepthMask(m_isDepthWriteEnabled);
+ glDepthFunc(m_depthFunc);
+ glFrontFace(m_frontFace);
+
+ if (m_polygonOffsetFillEnabled)
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ else
+ glDisable(GL_POLYGON_OFFSET_FILL);
+
+ glPolygonOffset(m_polygonOffsetFactor, m_polygonOffsetUnits);
+
+ glUseProgram(m_currentProgram);
+
+ glActiveTexture(m_activeTexture);
+ glBindTexture(GL_TEXTURE_2D, m_texBinding2D);
+
+ // Restore bound element array buffer and array buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_boundElementArrayBuffer);
+ for (int i = 0; i < m_maxVertexAttribs; i++) {
+ if (m_vertexAttribArrayEnabledStates[i])
+ glEnableVertexAttribArray(i);
+ else
+ glDisableVertexAttribArray(i);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexAttribArrayBoundBuffers[i]);
+ glVertexAttribPointer(i, m_vertexAttribArraySizes[i],
+ m_vertexAttribArrayTypes[i],
+ m_vertexAttribArrayNormalized[i],
+ m_vertexAttribArrayStrides[i],
+ m_vertexAttribArrayOffsets[i]);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_boundArrayBuffer);
+
+#ifdef VERBOSE_STATE_STORE
+ printCurrentState(false);
+#endif
+}
+
+void GLStateStore::initGLDefaultState()
+{
+#if !QT_CONFIG(opengles2)
+ m_drawFramebuffer = 0;
+ m_readFramebuffer = 0;
+ m_renderbuffer = 0;
+#endif
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 1.0f;
+ m_clearDepth = 1.0f;
+ m_isBlendingEnabled = GL_FALSE;
+ m_isDepthTestEnabled = GL_FALSE;
+ m_depthFunc = GL_LESS;
+ m_isDepthWriteEnabled = GL_TRUE;
+ m_currentProgram = 0;
+ m_texBinding2D = 0;
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ m_vertexAttribArrayEnabledStates[i] = GL_FALSE;
+ m_vertexAttribArrayBoundBuffers[i] = 0;
+ m_vertexAttribArraySizes[i] = 4;
+ m_vertexAttribArrayTypes[i] = GL_FLOAT;
+ m_vertexAttribArrayNormalized[i] = GL_FALSE;
+ m_vertexAttribArrayStrides[i] = 0;
+ m_vertexAttribArrayOffsets[i] = 0;
+ }
+ m_activeTexture = GL_TEXTURE0;
+ m_frontFace = GL_CCW;
+ m_isCullFaceEnabled = false;
+ m_cullFaceMode = GL_BACK;
+ m_blendEquationRGB = GL_FUNC_ADD;
+ m_blendEquationAlpha = GL_FUNC_ADD;
+ m_scissorBox[0] = 0;
+ m_scissorBox[1] = 0;
+ m_scissorBox[2] = 0;
+ m_scissorBox[3] = 0;
+ m_isScissorTestEnabled = GL_FALSE;
+
+ m_polygonOffsetFillEnabled = GL_FALSE;
+ m_polygonOffsetFactor = 0.0;
+ m_polygonOffsetUnits = 0.0;
+}
diff --git a/src/datavisualizationqml/glstatestore_p.h b/src/datavisualizationqml/glstatestore_p.h
new file mode 100644
index 00000000..f5aa0bdd
--- /dev/null
+++ b/src/datavisualizationqml/glstatestore_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVisualization 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.
+
+#ifndef GLSTATESTORE_P_H
+#define GLSTATESTORE_P_H
+
+#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QScopedArrayPointer>
+#include "enumtostringmap_p.h"
+
+class GLStateStore : public QObject, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ explicit GLStateStore(QOpenGLContext *context, QObject *parent = 0);
+ ~GLStateStore();
+
+ void storeGLState();
+ void restoreGLState();
+ void initGLDefaultState();
+
+#ifdef VERBOSE_STATE_STORE
+ void printCurrentState(bool in);
+ EnumToStringMap *m_map;
+#endif
+
+ GLint m_scissorBox[4];
+ GLboolean m_isScissorTestEnabled;
+
+#if !QT_CONFIG(opengles2)
+ GLint m_drawFramebuffer;
+ GLint m_readFramebuffer;
+ GLint m_renderbuffer;
+#endif
+ GLfloat m_clearColor[4];
+ GLfloat m_clearDepth;
+ GLboolean m_isBlendingEnabled;
+ GLboolean m_isDepthTestEnabled;
+ GLint m_depthFunc;
+ GLboolean m_isDepthWriteEnabled;
+ GLint m_currentProgram;
+ GLint m_maxVertexAttribs;
+ QScopedArrayPointer<GLint> m_vertexAttribArrayEnabledStates;
+ QScopedArrayPointer<GLint> m_vertexAttribArrayBoundBuffers;
+ QScopedArrayPointer<GLint> m_vertexAttribArraySizes;
+ QScopedArrayPointer<GLint> m_vertexAttribArrayTypes;
+ QScopedArrayPointer<GLint> m_vertexAttribArrayNormalized;
+ QScopedArrayPointer<GLint> m_vertexAttribArrayStrides;
+ QScopedArrayPointer<void *> m_vertexAttribArrayOffsets;
+
+ GLint m_activeTexture;
+ GLint m_texBinding2D;
+ GLint m_frontFace;
+ GLboolean m_isCullFaceEnabled;
+ GLint m_cullFaceMode;
+ GLint m_blendEquationRGB;
+ GLint m_blendEquationAlpha;
+ GLint m_blendDestAlpha;
+ GLint m_blendDestRGB;
+ GLint m_blendSrcAlpha;
+ GLint m_blendSrcRGB;
+ GLint m_boundArrayBuffer;
+ GLint m_boundElementArrayBuffer;
+ GLboolean m_polygonOffsetFillEnabled;
+ GLfloat m_polygonOffsetFactor;
+ GLfloat m_polygonOffsetUnits;
+};
+
+#endif