diff options
author | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-06-19 13:28:41 +0300 |
---|---|---|
committer | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-06-20 08:56:40 +0300 |
commit | 5fbf8b3259d882b4be6c1162d137be0d75493d8b (patch) | |
tree | 78e6cd5b9792c5f44e9f15376dec5764e8e52ce0 /src/datavis3dqml2 | |
parent | 331b719b61cc595943e9302d9750a7965a19fc9d (diff) |
3DMaps QML api added
Example still to be done
Change-Id: I959f4abaac9f3977998878b0cba665ca181a6b2c
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavis3dqml2')
-rw-r--r-- | src/datavis3dqml2/datavis3dqml2.pro | 3 | ||||
-rw-r--r-- | src/datavis3dqml2/datavis3dqml2_plugin.cpp | 1 | ||||
-rw-r--r-- | src/datavis3dqml2/declarativemaps.cpp | 294 | ||||
-rw-r--r-- | src/datavis3dqml2/declarativemaps.h | 130 | ||||
-rw-r--r-- | src/datavis3dqml2/declarativemaps_p.h | 75 |
5 files changed, 477 insertions, 26 deletions
diff --git a/src/datavis3dqml2/datavis3dqml2.pro b/src/datavis3dqml2/datavis3dqml2.pro index d87983b0..61f57cac 100644 --- a/src/datavis3dqml2/datavis3dqml2.pro +++ b/src/datavis3dqml2/datavis3dqml2.pro @@ -23,7 +23,8 @@ HEADERS += \ datavis3dqml2_plugin.h \ declarativebars.h \ declarativebars_p.h \ - declarativemaps.h #\ + declarativemaps.h \ + declarativemaps_p.h #\ #declarativedataitem.h \ #declarativedatarow.h \ #declarativedataset.h diff --git a/src/datavis3dqml2/datavis3dqml2_plugin.cpp b/src/datavis3dqml2/datavis3dqml2_plugin.cpp index 8dd029c9..3051e7ae 100644 --- a/src/datavis3dqml2/datavis3dqml2_plugin.cpp +++ b/src/datavis3dqml2/datavis3dqml2_plugin.cpp @@ -58,6 +58,7 @@ void Datavis3dqml2Plugin::registerTypes(const char *uri) qmlRegisterType<QDataSet>(uri, 1, 0, "DataSet"); qmlRegisterType<DeclarativeBars>(uri, 1, 0, "Bars3D"); + qmlRegisterType<DeclarativeMaps>(uri, 1, 0, "Maps3D"); } //#include "moc_datavis3dqml2_plugin.cpp" diff --git a/src/datavis3dqml2/declarativemaps.cpp b/src/datavis3dqml2/declarativemaps.cpp index eae80423..6356f89c 100644 --- a/src/datavis3dqml2/declarativemaps.cpp +++ b/src/datavis3dqml2/declarativemaps.cpp @@ -40,47 +40,315 @@ ****************************************************************************/ #include "declarativemaps.h" +#include "maps3dcontroller_p.h" +#include "qdatarow.h" +#include <QQuickWindow> +#include <QOpenGLFramebufferObject> +#include <QOpenGLContext> +#include <QGuiApplication> +#include <QThread> #include <QDebug> QT_DATAVIS3D_BEGIN_NAMESPACE -DeclarativeMaps::DeclarativeMaps() +DeclarativeMaps::DeclarativeMaps(QQuickItem *parent) + : QQuickItem(parent), + m_shared(0), + m_cachedState(new DeclarativeMapsCachedStatePrivate()), + m_initializedSize(0,0) { + setFlags(QQuickItem::ItemHasContents); + setAcceptedMouseButtons(Qt::AllButtons); + + // TODO: These seem to have no effect; find a way to activate anti-aliasing + setAntialiasing(true); + setSmooth(true); } DeclarativeMaps::~DeclarativeMaps() { + delete m_shared; +} + +void DeclarativeMaps::classBegin() +{ + qDebug() << "classBegin"; +} + +void DeclarativeMaps::componentComplete() +{ + qDebug() << "componentComplete"; +} + +QSGNode *DeclarativeMaps::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + if (!m_shared) { + m_shared = new Maps3DController(boundingRect().toRect()); + m_shared->initializeOpenGL(); + } + + // Check if properites have changed that need to be applied while on the SGRenderThread +// if (m_cachedState->m_data) { +// m_shared->addData(m_cachedState->m_data); +// m_cachedState->m_data = 0; +// } + + if (m_cachedState->m_isSelectionModeSet) { + m_shared->setSelectionMode(m_cachedState->m_selectionMode); + m_cachedState->m_isSelectionModeSet = false; + } + + if (m_cachedState->m_isLabelTransparencySet) { + m_shared->setLabelTransparency(m_cachedState->m_labelTransparency); + m_cachedState->m_isLabelTransparencySet = false; + } + + if (m_cachedState->m_isShadowQualitySet) { + m_shared->setShadowQuality(m_cachedState->m_shadowQuality); + m_cachedState->m_isShadowQualitySet = false; + } + + // If old node exists and has right size, reuse it. + if (oldNode && m_initializedSize == boundingRect().size().toSize()) { + // Update bounding rectangle (that has same size as before). + static_cast<DeclarativeMapsRenderer *>( oldNode )->setRect(boundingRect()); + return oldNode; + } + + // Create a new render node when size changes or if there is no node yet + m_initializedSize = boundingRect().size().toSize(); + + // Delete old node + if (oldNode) + delete oldNode; + + // Create a new one and set it's bounding rectangle + DeclarativeMapsRenderer *node = new DeclarativeMapsRenderer(window(), m_shared); + node->setRect(boundingRect()); + m_shared->setBoundingRect(boundingRect().toRect()); + return node; +} + +void DeclarativeMaps::setBarSpecs(const QVector3D &thickness, + Q3DMaps::AdjustmentDirection direction) +{ + m_shared->setBarSpecs(thickness, direction); +} + +void DeclarativeMaps::setBarType(BarStyle style, bool smooth) +{ + m_shared->setBarType(style, smooth); +} + +void DeclarativeMaps::setMeshFileName(const QString &objFileName) +{ + m_shared->setMeshFileName(objFileName); +} + +void DeclarativeMaps::setCameraPreset(CameraPreset preset) +{ + m_shared->setCameraPreset(preset); +} + +void DeclarativeMaps::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance) +{ + m_shared->setCameraPosition(horizontal, vertical, distance); +} + +void DeclarativeMaps::setTheme(ColorTheme theme) +{ + m_shared->setTheme(theme); +} + +void DeclarativeMaps::setBarColor(QColor baseColor, QColor heightColor, bool uniform) +{ + m_shared->setBarColor(baseColor, heightColor, uniform); +} + +void DeclarativeMaps::setAreaSpecs(const QRect &areaRect, const QImage &image) +{ + m_shared->setAreaSpecs(areaRect, image); +} + +void DeclarativeMaps::setImage(const QImage &image) +{ + m_shared->setImage(image); +} + +void DeclarativeMaps::setSelectionMode(DeclarativeMaps::SelectionMode mode) +{ + m_cachedState->m_selectionMode = QtDataVis3D::SelectionMode(mode); + m_cachedState->m_isSelectionModeSet = true; + update(); +} + +DeclarativeMaps::SelectionMode DeclarativeMaps::selectionMode() +{ + return DeclarativeMaps::SelectionMode(m_shared->selectionMode()); +} + +void DeclarativeMaps::setFontSize(float fontsize) +{ + m_shared->setFontSize(fontsize); } -void DeclarativeMaps::setSelMode(DeclarativeMaps::SelectionMode mode) +float DeclarativeMaps::fontSize() { - setSelectionMode(QtDataVis3D::SelectionMode(mode)); + return m_shared->fontSize(); } -DeclarativeMaps::SelectionMode DeclarativeMaps::selMode() +void DeclarativeMaps::setFont(const QFont &font) { - return DeclarativeMaps::SelectionMode(selectionMode()); + m_shared->setFont(font); } -void DeclarativeMaps::setTransparency(DeclarativeMaps::LabelTransparency transparency) +QFont DeclarativeMaps::font() { - setLabelTransparency(QtDataVis3D::LabelTransparency(transparency)); + return m_shared->font(); } -DeclarativeMaps::LabelTransparency DeclarativeMaps::transparency() +void DeclarativeMaps::setLabelTransparency(DeclarativeMaps::LabelTransparency transparency) { - return DeclarativeMaps::LabelTransparency(labelTransparency()); + m_cachedState->m_labelTransparency = QtDataVis3D::LabelTransparency(transparency); + m_cachedState->m_isLabelTransparencySet = true; + update(); } -void DeclarativeMaps::setShadow(DeclarativeMaps::ShadowQuality quality) +DeclarativeMaps::LabelTransparency DeclarativeMaps::labelTransparency() +{ + return DeclarativeMaps::LabelTransparency(m_shared->labelTransparency()); +} + +void DeclarativeMaps::setShadowQuality(DeclarativeMaps::ShadowQuality quality) +{ + m_cachedState->m_shadowQuality = QtDataVis3D::ShadowQuality(quality); + m_cachedState->m_isShadowQualitySet = true; + update(); +} + +DeclarativeMaps::ShadowQuality DeclarativeMaps::shadowQuality() +{ + return DeclarativeMaps::ShadowQuality(m_shared->shadowQuality()); +} + +bool DeclarativeMaps::addDataItem(QDataItem *dataItem) +{ + qDebug() << "Enter DeclarativeMaps::addDataItem(QDataItem *dataItem)"; + return m_shared->addDataItem(dataItem); +} + +bool DeclarativeMaps::addData(const QVector<QDataItem *> &data) +{ + qDebug() << "Enter DeclarativeMaps::addData(const QVector<QDataItem *> &data)"; + return m_shared->addData(data); +} + +bool DeclarativeMaps::addData(const QDataRow &dataRow) +{ + qDebug() << "Enter DeclarativeMaps::addData(const QDataRow &dataRow)"; + return m_shared->addData(dataRow); +} + +bool DeclarativeMaps::setData(const QVector<QDataItem *> &data) +{ + qDebug() << "Enter DeclarativeMaps::setData(const QVector<QDataItem *> &data)"; + return m_shared->setData(data); +} + +bool DeclarativeMaps::setData(QDataRow *data) +{ + qDebug() << "Enter DeclarativeMaps::setData(const QVector<QDataItem*> &data)"; + return m_shared->setData(data); +} + +void DeclarativeMaps::mousePressEvent(QMouseEvent *event) +{ + QPoint mousePos = event->pos(); + //mousePos.setY(height() - mousePos.y()); + m_shared->mousePressEvent(event, mousePos); +} + +void DeclarativeMaps::mouseReleaseEvent(QMouseEvent *event) +{ + QPoint mousePos = event->pos(); + //mousePos.setY(height() - mousePos.y()); + m_shared->mouseReleaseEvent(event, mousePos); +} + +void DeclarativeMaps::mouseMoveEvent(QMouseEvent *event) +{ + QPoint mousePos = event->pos(); + //mousePos.setY(height() - mousePos.y()); + m_shared->mouseMoveEvent(event, mousePos); +} + +void DeclarativeMaps::wheelEvent(QWheelEvent *event) +{ + m_shared->wheelEvent(event); +} + +DeclarativeMapsRenderer::DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *renderer) + : m_fbo(0), + m_texture(0), + m_window(window), + m_mapsRenderer(renderer) +{ + connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection); +} + +DeclarativeMapsRenderer::~DeclarativeMapsRenderer() +{ + delete m_texture; + delete m_fbo; +} + +void DeclarativeMapsRenderer::render() +{ + QSize size = rect().size().toSize(); + + // Create FBO + if (!m_fbo) { + QOpenGLFramebufferObjectFormat format; + format.setAttachment(QOpenGLFramebufferObject::Depth); + m_fbo = new QOpenGLFramebufferObject(size, format); + m_texture = m_window->createTextureFromId(m_fbo->texture(), size); + + setTexture(m_texture); + + // Flip texture + // TODO: Can be gotten rid of once support for texture flipping becomes available (in Qt5.2) + QSize ts = m_texture->textureSize(); + QRectF sourceRect(0, 0, ts.width(), ts.height()); + float tmp = sourceRect.top(); + sourceRect.setTop(sourceRect.bottom()); + sourceRect.setBottom(tmp); + QSGGeometry *geometry = this->geometry(); + QSGGeometry::updateTexturedRectGeometry(geometry, rect(), + m_texture->convertToNormalizedSourceRect(sourceRect)); + markDirty(DirtyMaterial); + //qDebug() << "create node" << m_fbo->handle() << m_texture->textureId() << m_fbo->size(); + } + + // Call the shared rendering function + m_fbo->bind(); + + m_mapsRenderer->render(m_fbo->handle()); + + m_fbo->release(); + + // New view is in the FBO, request repaint of scene graph + m_window->update(); +} + + +DeclarativeMapsCachedStatePrivate::DeclarativeMapsCachedStatePrivate() + : m_data(0) { - setShadowQuality(QtDataVis3D::ShadowQuality(quality)); } -DeclarativeMaps::ShadowQuality DeclarativeMaps::shadow() +DeclarativeMapsCachedStatePrivate::~DeclarativeMapsCachedStatePrivate() { - return DeclarativeMaps::ShadowQuality(shadowQuality()); } QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3dqml2/declarativemaps.h b/src/datavis3dqml2/declarativemaps.h index d01232c9..78c11641 100644 --- a/src/datavis3dqml2/declarativemaps.h +++ b/src/datavis3dqml2/declarativemaps.h @@ -42,18 +42,31 @@ #ifndef DECLARATIVEMAPS_H #define DECLARATIVEMAPS_H +#include "maps3dcontroller_p.h" #include "qdatavis3dglobal.h" #include "qdatavis3namespace.h" -#include "q3dmaps.h" +#include "declarativemaps_p.h" + +#include <qsgsimpletexturenode.h> +#include <QQuickItem> +#include <QObject> + +class QOpenGLFramebufferObject; +class QSGTexture; +class QQuickWindow; QT_DATAVIS3D_BEGIN_NAMESPACE -class DeclarativeMaps : public Q3DMaps +class DeclarativeMaps : public QQuickItem { Q_OBJECT - Q_PROPERTY(SelectionMode selectionMode READ selMode WRITE setSelMode) - Q_PROPERTY(LabelTransparency labelTransparency READ transparency WRITE setTransparency) - Q_PROPERTY(ShadowQuality shadowQuality READ shadow WRITE setShadow) + Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + Q_PROPERTY(LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency) + Q_PROPERTY(ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize) + Q_PROPERTY(int width READ width WRITE setWidth) + Q_PROPERTY(int height READ height WRITE setHeight) Q_ENUMS(SelectionMode) Q_ENUMS(ShadowQuality) Q_ENUMS(LabelTransparency) @@ -84,20 +97,113 @@ public: }; public: - explicit DeclarativeMaps(); + explicit DeclarativeMaps(QQuickItem *parent = 0); ~DeclarativeMaps(); + void classBegin(); + void componentComplete(); + + // Add data item. New data item is appended to old data. + // ownership of data is transferred + Q_INVOKABLE bool addDataItem(QDataItem *dataItem); + + // Add data set. New data is appended to old data. + // ownership of data is transferred + Q_INVOKABLE bool addData(const QVector<QDataItem *> &data); + // ownership of data is transferred + Q_INVOKABLE bool addData(const QDataRow &data); + + // Add data set. Old data is deleted. + // ownership of data is transferred + Q_INVOKABLE bool setData(const QVector<QDataItem *> &data); + // ownership of data is transferred + Q_INVOKABLE bool setData(QDataRow *data); + + // bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value + // TODO: Start using thickness also in adjustment direction; use it as a relative value. + // For example, in AdjustAll mode setting thickness to (0.1f, 1.0f, 0.5f) would apply value to + // x at 10%, y at 100% and z at 50%. If a dimension is not included, given thickness states its absolute value. + Q_INVOKABLE void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f), + Q3DMaps::AdjustmentDirection direction = Q3DMaps::AdjustHeight); + + // bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc. + Q_INVOKABLE void setBarType(BarStyle style, bool smooth = false); + + // override bar type with own mesh + Q_INVOKABLE void setMeshFileName(const QString &objFileName); + + // Select preset camera placement + Q_INVOKABLE void setCameraPreset(CameraPreset preset); + + // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and + // vertical (0...90) angles and distance in percentage (10...500)) + Q_INVOKABLE void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100); + + // Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected) + Q_INVOKABLE void setTheme(ColorTheme theme); + + // Set color if you don't want to use themes. Set uniform to false if you want the (height) color to change from bottom to top + Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true); + + // Set area specs + Q_INVOKABLE void setAreaSpecs(const QRect &areaRect, const QImage &image); + + // Set area image + Q_INVOKABLE void setImage(const QImage &image); + + // TODO: light placement API + // Change selection mode; single bar, bar and row, bar and column, or all - void setSelMode(DeclarativeMaps::SelectionMode mode); - DeclarativeMaps::SelectionMode selMode(); + void setSelectionMode(SelectionMode mode); + SelectionMode selectionMode(); + + // Font size adjustment + void setFontSize(float fontsize); + float fontSize(); + + // Set font + void setFont(const QFont &font); + QFont font(); // Label transparency adjustment - void setTransparency(DeclarativeMaps::LabelTransparency transparency); - DeclarativeMaps::LabelTransparency transparency(); + void setLabelTransparency(LabelTransparency transparency); + LabelTransparency labelTransparency(); // Adjust shadow quality - void setShadow(DeclarativeMaps::ShadowQuality quality); - DeclarativeMaps::ShadowQuality shadow(); + void setShadowQuality(ShadowQuality quality); + ShadowQuality shadowQuality(); + +protected: + Maps3DController *m_shared; + DeclarativeMapsCachedStatePrivate *m_cachedState; + QSize m_initializedSize; + + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); +}; + +// TODO: If we use texture node, our rendering is done into a texture that is then drawn to the +// qquickwindow -> selection will not work +class DeclarativeMapsRenderer : public QObject, public QSGSimpleTextureNode +{ + Q_OBJECT + +public: + DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *shared); + ~DeclarativeMapsRenderer(); + +public slots: + void render(); + +private: + QOpenGLFramebufferObject *m_fbo; + QSGTexture *m_texture; + QQuickWindow *m_window; + Maps3DController *m_mapsRenderer; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3dqml2/declarativemaps_p.h b/src/datavis3dqml2/declarativemaps_p.h new file mode 100644 index 00000000..07a83225 --- /dev/null +++ b/src/datavis3dqml2/declarativemaps_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DECLARATIVEMAPS_P_H +#define DECLARATIVEMAPS_P_H + +#include "qdatavis3dglobal.h" +#include "qdatavis3namespace.h" +#include <QString> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QDataRow; + +class DeclarativeMapsCachedStatePrivate +{ +public: + explicit DeclarativeMapsCachedStatePrivate(); + ~DeclarativeMapsCachedStatePrivate(); + + int m_cachedState; + + QDataRow *m_data; + + bool m_isSelectionModeSet; + SelectionMode m_selectionMode; + + bool m_isLabelTransparencySet; + LabelTransparency m_labelTransparency; + + bool m_isShadowQualitySet; + ShadowQuality m_shadowQuality; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif |