diff options
Diffstat (limited to 'src/datavisualization/data')
46 files changed, 738 insertions, 238 deletions
diff --git a/src/datavisualization/data/abstractitemmodelhandler.cpp b/src/datavisualization/data/abstractitemmodelhandler.cpp index 63eb7e45..9f2ccd86 100644 --- a/src/datavisualization/data/abstractitemmodelhandler.cpp +++ b/src/datavisualization/data/abstractitemmodelhandler.cpp @@ -17,7 +17,6 @@ ****************************************************************************/ #include "abstractitemmodelhandler_p.h" -#include <QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/abstractitemmodelhandler_p.h b/src/datavisualization/data/abstractitemmodelhandler_p.h index c238a63b..ecbfe61c 100644 --- a/src/datavisualization/data/abstractitemmodelhandler_p.h +++ b/src/datavisualization/data/abstractitemmodelhandler_p.h @@ -30,9 +30,9 @@ #define ABSTRACTITEMMODELHANDLER_P_H #include "datavisualizationglobal_p.h" -#include <QAbstractItemModel> -#include <QPointer> -#include <QTimer> +#include <QtCore/QAbstractItemModel> +#include <QtCore/QPointer> +#include <QtCore/QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/abstractrenderitem.cpp b/src/datavisualization/data/abstractrenderitem.cpp index 522fd144..59ffab22 100644 --- a/src/datavisualization/data/abstractrenderitem.cpp +++ b/src/datavisualization/data/abstractrenderitem.cpp @@ -21,39 +21,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION AbstractRenderItem::AbstractRenderItem() - : m_selectionLabelItem(0) { } AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other) { - m_selectionLabel = other.m_selectionLabel; m_translation = other.m_translation; - m_selectionLabelItem = 0; + m_rotation = other.m_rotation; } AbstractRenderItem::~AbstractRenderItem() { - delete m_selectionLabelItem; -} - -LabelItem &AbstractRenderItem::selectionLabelItem() -{ - if (!m_selectionLabelItem) - m_selectionLabelItem = new LabelItem; - return *m_selectionLabelItem; -} - -void AbstractRenderItem::setSelectionLabel(const QString &label) -{ - if (m_selectionLabelItem) - m_selectionLabelItem->clear(); - m_selectionLabel = label; -} - -QString &AbstractRenderItem::selectionLabel() -{ - return m_selectionLabel; } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h index fa06db54..912a09f3 100644 --- a/src/datavisualization/data/abstractrenderitem_p.h +++ b/src/datavisualization/data/abstractrenderitem_p.h @@ -32,10 +32,10 @@ #include "datavisualizationglobal_p.h" #include "labelitem_p.h" -#include <QOpenGLFunctions> -#include <QString> -#include <QVector3D> -#include <QQuaternion> +#include <QtCore/QString> +#include <QtGui/QOpenGLFunctions> +#include <QtGui/QVector3D> +#include <QtGui/QQuaternion> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -50,17 +50,16 @@ public: inline void setTranslation(const QVector3D &translation) { m_translation = translation; } inline const QVector3D &translation() const {return m_translation; } - // Selection label item (containing special selection texture, if mode is activated) - LabelItem &selectionLabelItem(); - - // Formatted selection label for item. - void setSelectionLabel(const QString &label); - QString &selectionLabel(); // Formats selection label if not previously formatted + inline QQuaternion rotation() const { return m_rotation; } + inline void setRotation(const QQuaternion &rotation) + { + if (m_rotation != rotation) + m_rotation = rotation; + } protected: - QString m_selectionLabel; QVector3D m_translation; - LabelItem *m_selectionLabelItem; + QQuaternion m_rotation; friend class QAbstractDataItem; }; diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp index 611fbcb9..4f44fe1d 100644 --- a/src/datavisualization/data/baritemmodelhandler.cpp +++ b/src/datavisualization/data/baritemmodelhandler.cpp @@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +static const int noRoleIndex = -1; + BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent) : AbstractItemModelHandler(parent), m_proxy(proxy), @@ -51,8 +53,9 @@ void BarItemModelHandler::resolveModel() QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); - // Default to display role if no mapping + // Default value role to display role if no mapping int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole); + int rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex); int rowCount = m_itemModel->rowCount(); int columnCount = m_itemModel->columnCount(); @@ -67,8 +70,11 @@ void BarItemModelHandler::resolveModel() } for (int i = 0; i < rowCount; i++) { QBarDataRow &newProxyRow = *m_proxyArray->at(i); - for (int j = 0; j < columnCount; j++) + for (int j = 0; j < columnCount; j++) { newProxyRow[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal()); + if (rotationRole != noRoleIndex) + newProxyRow[j].setRotation(m_itemModel->index(i, j).data(rotationRole).toReal()); + } } // Generate labels from headers if using model rows/columns for (int i = 0; i < rowCount; i++) @@ -92,12 +98,15 @@ void BarItemModelHandler::resolveModel() // Sort values into rows and columns typedef QHash<QString, float> ColumnValueMap; QHash <QString, ColumnValueMap> itemValueMap; + QHash <QString, ColumnValueMap> itemRotationMap; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { QModelIndex index = m_itemModel->index(i, j); QString rowRoleStr = index.data(rowRole).toString(); QString columnRoleStr = index.data(columnRole).toString(); itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal(); + if (rotationRole != noRoleIndex) + itemRotationMap[rowRoleStr][columnRoleStr] = index.data(rotationRole).toReal(); if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); rowList << rowRoleStr; @@ -131,8 +140,11 @@ void BarItemModelHandler::resolveModel() for (int i = 0; i < rowList.size(); i++) { QString rowKey = rowList.at(i); QBarDataRow &newProxyRow = *m_proxyArray->at(i); - for (int j = 0; j < columnList.size(); j++) + for (int j = 0; j < columnList.size(); j++) { newProxyRow[j].setValue(itemValueMap[rowKey][columnList.at(j)]); + if (rotationRole != noRoleIndex) + newProxyRow[j].setRotation(itemRotationMap[rowKey][columnList.at(j)]); + } } rowLabels = rowList; diff --git a/src/datavisualization/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp index 915f3f78..50d2a4b4 100644 --- a/src/datavisualization/data/barrenderitem.cpp +++ b/src/datavisualization/data/barrenderitem.cpp @@ -25,7 +25,6 @@ BarRenderItem::BarRenderItem() : AbstractRenderItem(), m_value(0), m_height(0.0f), - m_sliceLabelItem(0), m_seriesIndex(0) { } @@ -36,32 +35,58 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other) m_value = other.m_value; m_position = other.m_position; m_height = other.m_height; - m_sliceLabel = other.m_sliceLabel; - m_sliceLabelItem = 0; m_seriesIndex = other.m_seriesIndex; - m_rotation = other.m_rotation; } BarRenderItem::~BarRenderItem() { +} + +BarRenderSliceItem::BarRenderSliceItem() + : BarRenderItem(), + m_sliceLabelItem(0) +{ +} + +BarRenderSliceItem::BarRenderSliceItem(const BarRenderSliceItem &other) + : BarRenderItem(other) +{ + m_sliceLabel = other.m_sliceLabel; + m_sliceLabelItem = 0; +} + +BarRenderSliceItem::~BarRenderSliceItem() +{ delete m_sliceLabelItem; } -LabelItem &BarRenderItem::sliceLabelItem() +void BarRenderSliceItem::setItem(const BarRenderItem &renderItem) +{ + m_translation = renderItem.translation(); + m_rotation = renderItem.rotation(); + m_value = renderItem.value(); + m_position = renderItem.position(); + m_height = renderItem.height(); + m_seriesIndex = renderItem.seriesIndex(); + m_sliceLabel = QString(); + m_sliceLabelItem = 0; +} + +LabelItem &BarRenderSliceItem::sliceLabelItem() { if (!m_sliceLabelItem) m_sliceLabelItem = new LabelItem; return *m_sliceLabelItem; } -void BarRenderItem::setSliceLabel(const QString &label) +void BarRenderSliceItem::setSliceLabel(const QString &label) { if (m_sliceLabelItem) m_sliceLabelItem->clear(); m_sliceLabel = label; } -const QString &BarRenderItem::sliceLabel() const +const QString &BarRenderSliceItem::sliceLabel() const { return m_sliceLabel; } diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h index e1062969..1122053d 100644 --- a/src/datavisualization/data/barrenderitem_p.h +++ b/src/datavisualization/data/barrenderitem_p.h @@ -47,48 +47,49 @@ public: inline const QPoint &position() const { return m_position; } // Actual cached data value of the bar (needed to trigger label reformats) - inline void setValue(float value) - { - m_value = value; - // Force reformatting on next access by setting label string to null string - if (!m_sliceLabel.isNull()) - setSliceLabel(QString()); - if (!m_selectionLabel.isNull()) - setSelectionLabel(QString()); - } + inline void setValue(float value) { m_value = value; } inline float value() const { return m_value; } // Normalized bar height inline void setHeight(GLfloat height) { m_height = height; } inline GLfloat height() const { return m_height; } - // Label item for formatted label - LabelItem &sliceLabelItem(); - - // Formatted label for item. - void setSliceLabel(const QString &label); - const QString &sliceLabel() const; // Formats label if not previously formatted - // Series index in visual series that this item belongs to. // This is only utilized by slicing, so it may not be up to date on all items. inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; } inline int seriesIndex() const { return m_seriesIndex; } - inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; } - inline const QQuaternion &rotation() const { return m_rotation; } - protected: float m_value; QPoint m_position; // x = row, y = column GLfloat m_height; - QString m_sliceLabel; - LabelItem *m_sliceLabelItem; int m_seriesIndex; - QQuaternion m_rotation; friend class QBarDataItem; }; +class BarRenderSliceItem : public BarRenderItem +{ +public: + BarRenderSliceItem(); + BarRenderSliceItem(const BarRenderSliceItem &other); + virtual ~BarRenderSliceItem(); + + void setItem(const BarRenderItem &renderItem); + + // Label item for formatted label + LabelItem &sliceLabelItem(); + + // Formatted label for item. + void setSliceLabel(const QString &label); + const QString &sliceLabel() const; // Formats label if not previously formatted + +protected: + QString m_sliceLabel; + LabelItem *m_sliceLabelItem; + bool m_isNull; +}; + typedef QVector<BarRenderItem> BarRenderItemRow; typedef QVector<BarRenderItemRow> BarRenderItemArray; diff --git a/src/datavisualization/data/labelitem_p.h b/src/datavisualization/data/labelitem_p.h index ca60f742..3a2c1eb1 100644 --- a/src/datavisualization/data/labelitem_p.h +++ b/src/datavisualization/data/labelitem_p.h @@ -30,8 +30,8 @@ #define LABELITEM_P_H #include "datavisualizationglobal_p.h" -#include <QOpenGLFunctions> -#include <QSize> +#include <QtGui/QOpenGLFunctions> +#include <QtCore/QSize> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp index dc241fdb..4d201c45 100644 --- a/src/datavisualization/data/qabstract3dseries.cpp +++ b/src/datavisualization/data/qabstract3dseries.cpp @@ -240,6 +240,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle) + * + * A convenience function to construct mesh rotation quaternion from axis and angle. + * + * \sa meshRotation + */ + +/*! * \internal */ QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) : @@ -375,6 +383,16 @@ QQuaternion QAbstract3DSeries::meshRotation() const } /*! + * A convenience function to construct mesh rotation quaternion from \a axis and \a angle. + * + * \sa meshRotation + */ +void QAbstract3DSeries::setMeshAxisAndAngle(const QVector3D &axis, float angle) +{ + setMeshRotation(QQuaternion::fromAxisAndAngle(axis, angle)); +} + +/*! * \property QAbstract3DSeries::userDefinedMesh * * Sets the \a fileName for user defined custom mesh for objects that is used when mesh diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h index ebb22b7f..9f82901d 100644 --- a/src/datavisualization/data/qabstract3dseries.h +++ b/src/datavisualization/data/qabstract3dseries.h @@ -20,10 +20,11 @@ #define QABSTRACT3DSERIES_H #include <QtDataVisualization/q3dtheme.h> -#include <QObject> -#include <QScopedPointer> -#include <QLinearGradient> -#include <QQuaternion> +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> +#include <QtCore/QString> +#include <QtGui/QLinearGradient> +#include <QtGui/QQuaternion> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -95,6 +96,7 @@ public: void setMeshRotation(const QQuaternion &rotation); QQuaternion meshRotation() const; + Q_INVOKABLE void setMeshAxisAndAngle(const QVector3D &axis, float angle); void setUserDefinedMesh(const QString &fileName); QString userDefinedMesh() const; @@ -118,20 +120,20 @@ public: QString name() const; signals: - void itemLabelFormatChanged(QString format); + void itemLabelFormatChanged(const QString &format); void visibilityChanged(bool visible); void meshChanged(Mesh mesh); void meshSmoothChanged(bool enabled); - void meshRotationChanged(QQuaternion rotation); - void userDefinedMeshChanged(QString fileName); + void meshRotationChanged(const QQuaternion &rotation); + void userDefinedMeshChanged(const QString &fileName); void colorStyleChanged(Q3DTheme::ColorStyle style); - void baseColorChanged(QColor color); - void baseGradientChanged(QLinearGradient gradient); - void singleHighlightColorChanged(QColor color); - void singleHighlightGradientChanged(QLinearGradient gradient); - void multiHighlightColorChanged(QColor color); - void multiHighlightGradientChanged(QLinearGradient gradient); - void nameChanged(QString name); + void baseColorChanged(const QColor &color); + void baseGradientChanged(const QLinearGradient &gradient); + void singleHighlightColorChanged(const QColor &color); + void singleHighlightGradientChanged(const QLinearGradient &gradient); + void multiHighlightColorChanged(const QColor &color); + void multiHighlightGradientChanged(const QLinearGradient &gradient); + void nameChanged(const QString &name); protected: QScopedPointer<QAbstract3DSeriesPrivate> d_ptr; @@ -142,6 +144,7 @@ private: friend class Abstract3DController; friend class Bars3DController; friend class Surface3DController; + friend class Surface3DRenderer; friend class Scatter3DController; friend class QBar3DSeries; friend class SeriesRenderCache; diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h index 6fbabd3d..a803e99b 100644 --- a/src/datavisualization/data/qabstract3dseries_p.h +++ b/src/datavisualization/data/qabstract3dseries_p.h @@ -28,7 +28,6 @@ #include "datavisualizationglobal_p.h" #include "qabstract3dseries.h" -#include <QString> #ifndef QABSTRACT3DSERIES_P_H #define QABSTRACT3DSERIES_P_H diff --git a/src/datavisualization/data/qabstractdataproxy.h b/src/datavisualization/data/qabstractdataproxy.h index 52c2e2c6..c643c675 100644 --- a/src/datavisualization/data/qabstractdataproxy.h +++ b/src/datavisualization/data/qabstractdataproxy.h @@ -20,9 +20,8 @@ #define QABSTRACTDATAPROXY_H #include <QtDataVisualization/qdatavisualizationglobal.h> - -#include <QObject> -#include <QScopedPointer> +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h index 093629d5..eb901f4c 100644 --- a/src/datavisualization/data/qabstractdataproxy_p.h +++ b/src/datavisualization/data/qabstractdataproxy_p.h @@ -28,7 +28,6 @@ #include "datavisualizationglobal_p.h" #include "qabstractdataproxy.h" -#include <QString> #ifndef QABSTRACTDATAPROXY_P_H #define QABSTRACTDATAPROXY_P_H diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp index 1440476b..ed4ffaba 100644 --- a/src/datavisualization/data/qbar3dseries.cpp +++ b/src/datavisualization/data/qbar3dseries.cpp @@ -18,6 +18,7 @@ #include "qbar3dseries_p.h" #include "bars3dcontroller_p.h" +#include <QtCore/qmath.h> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -114,6 +115,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty real Bar3DSeries::meshAngle + * + * A convenience property for defining the series rotation \a angle in degrees. + * + * \note: When reading this property, it is calculated from Abstract3DSeries::meshRotation value + * using floating point precision and always returns a value from zero to 360 degrees. + * + * \sa Abstract3DSeries::meshRotation + */ + +/*! * Constructs QBar3DSeries with the given \a parent. */ QBar3DSeries::QBar3DSeries(QObject *parent) : @@ -121,6 +133,7 @@ QBar3DSeries::QBar3DSeries(QObject *parent) : { // Default proxy dptr()->setDataProxy(new QBarDataProxy); + dptr()->connectSignals(); } /*! @@ -130,14 +143,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent) { dptr()->setDataProxy(dataProxy); -} - -/*! - * \internal - */ -QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) : - QAbstract3DSeries(d, parent) -{ + dptr()->connectSignals(); } /*! @@ -183,7 +189,7 @@ void QBar3DSeries::setSelectedBar(const QPoint &position) { // Don't do this in private to avoid loops, as that is used for callback from controller. if (d_ptr->m_controller) - static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this); + static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this, true); else dptr()->setSelectedBar(position); } @@ -204,6 +210,38 @@ QPoint QBar3DSeries::invalidSelectionPosition() return Bars3DController::invalidSelectionPosition(); } +static inline float quaternionAngle(const QQuaternion &rotation) +{ + return qAcos(rotation.scalar()) * 360.0f / M_PI; +} + +/*! + * \property QBar3DSeries::meshAngle + * + * A convenience property for defining the series rotation \a angle in degrees. + * Setting this property is equivalent to the following call: + * \code setMeshRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, angle)) \endcode + * + * \note: When reading this property, it is calculated from QAbstract3DSeries::meshRotation value + * using floating point precision and always returns a value from zero to 360 degrees. + * + * \sa QAbstract3DSeries::meshRotation + */ +void QBar3DSeries::setMeshAngle(float angle) +{ + setMeshRotation(QQuaternion::fromAxisAndAngle(upVector, angle)); +} + +float QBar3DSeries::meshAngle() const +{ + QQuaternion rotation = meshRotation(); + + if (rotation.isIdentity() || rotation.x() != 0.0f || rotation.z() != 0.0f) + return 0.0f; + else + return quaternionAngle(rotation); +} + /*! * \internal */ @@ -279,6 +317,11 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon } } +void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation) +{ + emit qptr()->meshAngleChanged(quaternionAngle(rotation)); +} + void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position) { if (position != m_selectedBar) { @@ -287,4 +330,10 @@ void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position) } } +void QBar3DSeriesPrivate::connectSignals() +{ + QObject::connect(q_ptr, &QAbstract3DSeries::meshRotationChanged, this, + &QBar3DSeriesPrivate::handleMeshRotationChanged); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h index be748516..c56bc354 100644 --- a/src/datavisualization/data/qbar3dseries.h +++ b/src/datavisualization/data/qbar3dseries.h @@ -21,7 +21,7 @@ #include <QtDataVisualization/qabstract3dseries.h> #include <QtDataVisualization/qbardataproxy.h> -#include <QPoint> +#include <QtCore/QPoint> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -32,6 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QBar3DSeries : public QAbstract3DSeries Q_OBJECT Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged) Q_PROPERTY(QPoint selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged) + Q_PROPERTY(float meshAngle READ meshAngle WRITE setMeshAngle NOTIFY meshAngleChanged) public: explicit QBar3DSeries(QObject *parent = 0); @@ -45,12 +46,15 @@ public: QPoint selectedBar() const; static QPoint invalidSelectionPosition(); + void setMeshAngle(float angle); + float meshAngle() const; + signals: void dataProxyChanged(QBarDataProxy *proxy); - void selectedBarChanged(QPoint position); + void selectedBarChanged(const QPoint &position); + void meshAngleChanged(float angle); protected: - explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0); QBar3DSeriesPrivate *dptr(); const QBar3DSeriesPrivate *dptrc() const; diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h index 173f1cd9..718f1237 100644 --- a/src/datavisualization/data/qbar3dseries_p.h +++ b/src/datavisualization/data/qbar3dseries_p.h @@ -44,8 +44,12 @@ public: virtual void setDataProxy(QAbstractDataProxy *proxy); virtual void connectControllerAndProxy(Abstract3DController *newController); + void handleMeshRotationChanged(const QQuaternion &rotation); + void setSelectedBar(const QPoint &position); + void connectSignals(); + private: QBar3DSeries *qptr(); diff --git a/src/datavisualization/data/qbardataitem.h b/src/datavisualization/data/qbardataitem.h index 84e7cd92..e7fce93b 100644 --- a/src/datavisualization/data/qbardataitem.h +++ b/src/datavisualization/data/qbardataitem.h @@ -42,7 +42,7 @@ public: inline float rotation() const { return m_angle; } protected: - virtual void createExtraData(); + void createExtraData(); QBarDataItemPrivate *d_ptr; diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp index a26e446e..d2553f32 100644 --- a/src/datavisualization/data/qbardataproxy.cpp +++ b/src/datavisualization/data/qbardataproxy.cpp @@ -130,7 +130,7 @@ QBarDataProxy::~QBarDataProxy() * * The series this proxy is attached to. */ -QBar3DSeries *QBarDataProxy::series() +QBar3DSeries *QBarDataProxy::series() const { return static_cast<QBar3DSeries *>(d_ptr->series()); } @@ -227,6 +227,15 @@ void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &i } /*! + * Changes a single item at \a position to the \a item. + * The X-value of \a position indicates the row and the Y-value indicates the column. + */ +void QBarDataProxy::setItem(const QPoint &position, const QBarDataItem &item) +{ + setItem(position.x(), position.y(), item); +} + +/*! * Adds a new \a row to the end of array. * Existing row labels are not affected. * @@ -427,6 +436,16 @@ const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const } /*! + * \return pointer to the item at \a position. The X-value of \a position indicates the row + * and the Y-value indicates the column. The item is guaranteed to be valid only + * until the next call that modifies data. + */ +const QBarDataItem *QBarDataProxy::itemAt(const QPoint &position) const +{ + return itemAt(position.x(), position.y()); +} + +/*! * \internal */ QBarDataProxyPrivate *QBarDataProxy::dptr() diff --git a/src/datavisualization/data/qbardataproxy.h b/src/datavisualization/data/qbardataproxy.h index 0ad71365..55c11de3 100644 --- a/src/datavisualization/data/qbardataproxy.h +++ b/src/datavisualization/data/qbardataproxy.h @@ -21,8 +21,8 @@ #include <QtDataVisualization/qabstractdataproxy.h> #include <QtDataVisualization/qbardataitem.h> -#include <QVector> -#include <QStringList> +#include <QtCore/QVector> +#include <QtCore/QStringList> namespace QtDataVisualization { // typedefs introduced this way because QDoc doesn't understand namespace macros @@ -47,7 +47,7 @@ public: explicit QBarDataProxy(QObject *parent = 0); virtual ~QBarDataProxy(); - QBar3DSeries *series(); + QBar3DSeries *series() const; int rowCount() const; QStringList rowLabels() const; @@ -58,6 +58,7 @@ public: const QBarDataArray *array() const; const QBarDataRow *rowAt(int rowIndex) const; const QBarDataItem *itemAt(int rowIndex, int columnIndex) const; + const QBarDataItem *itemAt(const QPoint &position) const; void resetArray(); void resetArray(QBarDataArray *newArray); @@ -70,6 +71,7 @@ public: void setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels); void setItem(int rowIndex, int columnIndex, const QBarDataItem &item); + void setItem(const QPoint &position, const QBarDataItem &item); int addRow(QBarDataRow *row); int addRow(QBarDataRow *row, const QString &label); diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp index 9ac5c90f..1aead1d7 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp @@ -134,6 +134,18 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObj } /*! + * Constructs QHeightMapSurfaceDataProxy from the given image \a filename and \a parent. Height map is set + * by calling setHeightMapFile() with \a filename. + * + * \sa heightMapFile + */ +QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent) : + QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent) +{ + setHeightMapFile(filename); +} + +/*! * \internal */ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy( diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h index d506d4e8..5b6eb284 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy.h +++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h @@ -20,8 +20,8 @@ #define QHEIGHTMAPSURFACEDATAPROXY_H #include <QtDataVisualization/qsurfacedataproxy.h> - -#include <QImage> +#include <QtGui/QImage> +#include <QtCore/QString> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -41,6 +41,7 @@ class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDa public: explicit QHeightMapSurfaceDataProxy(QObject *parent = 0); explicit QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent = 0); + explicit QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent = 0); virtual ~QHeightMapSurfaceDataProxy(); void setHeightMap(const QImage &image); @@ -59,8 +60,8 @@ public: float maxZValue() const; signals: - void heightMapChanged(QImage image); - void heightMapFileChanged(QString filename); + void heightMapChanged(const QImage &image); + void heightMapFileChanged(const QString &filename); void minXValueChanged(float value); void maxXValueChanged(float value); void minZValueChanged(float value); diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h index 0e947666..5cc9993a 100644 --- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h +++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h @@ -31,7 +31,7 @@ #include "qheightmapsurfacedataproxy.h" #include "qsurfacedataproxy_p.h" -#include <QTimer> +#include <QtCore/QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp index 97289da1..0e880c77 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy.cpp +++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp @@ -18,7 +18,6 @@ #include "qitemmodelbardataproxy_p.h" #include "baritemmodelhandler_p.h" -#include <QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -105,6 +104,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty string ItemModelBarDataProxy::rotationRole + * + * Defines the rotation role for the mapping. + */ + +/*! * \qmlproperty list ItemModelBarDataProxy::rowCategories * The row categories of the mapping. Only items with row roles that are found in this list are * included when the data is resolved. The rows are ordered in the same order as they are in this list. @@ -195,6 +200,27 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod /*! * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take * ownership of the \a itemModel, as typically item models are owned by other controls. + * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole. + */ +QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel, + const QString &rowRole, + const QString &columnRole, + const QString &valueRole, + const QString &rotationRole, + QObject *parent) + : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent) +{ + dptr()->m_itemModelHandler->setItemModel(itemModel); + dptr()->m_rowRole = rowRole; + dptr()->m_columnRole = columnRole; + dptr()->m_valueRole = valueRole; + dptr()->m_rotationRole = rotationRole; + dptr()->connectItemModelHandler(); +} + +/*! + * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take + * ownership of the \a itemModel, as typically item models are owned by other controls. * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole. * Row and column categories are set with \a rowCategories and \a columnCategories. * This constructor also sets autoRowCategories and autoColumnCategories to false. @@ -220,6 +246,35 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod } /*! + * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take + * ownership of the \a itemModel, as typically item models are owned by other controls. + * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole. + * Row and column categories are set with \a rowCategories and \a columnCategories. + * This constructor also sets autoRowCategories and autoColumnCategories to false. + */ +QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel, + const QString &rowRole, + const QString &columnRole, + const QString &valueRole, + const QString &rotationRole, + const QStringList &rowCategories, + const QStringList &columnCategories, + QObject *parent) + : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent) +{ + dptr()->m_itemModelHandler->setItemModel(itemModel); + dptr()->m_rowRole = rowRole; + dptr()->m_columnRole = columnRole; + dptr()->m_valueRole = valueRole; + dptr()->m_rotationRole = rotationRole; + dptr()->m_rowCategories = rowCategories; + dptr()->m_columnCategories = columnCategories; + dptr()->m_autoRowCategories = false; + dptr()->m_autoColumnCategories = false; + dptr()->connectItemModelHandler(); +} + +/*! * Destroys QItemModelBarDataProxy. */ QItemModelBarDataProxy::~QItemModelBarDataProxy() @@ -297,6 +352,24 @@ QString QItemModelBarDataProxy::valueRole() const } /*! + * \property QItemModelBarDataProxy::rotationRole + * + * Defines the rotation role for the mapping. + */ +void QItemModelBarDataProxy::setRotationRole(const QString &role) +{ + if (dptr()->m_rotationRole != role) { + dptr()->m_rotationRole = role; + emit rotationRoleChanged(role); + } +} + +QString QItemModelBarDataProxy::rotationRole() const +{ + return dptrc()->m_rotationRole; +} + +/*! * \property QItemModelBarDataProxy::rowCategories * * Defines the row categories for the mapping. @@ -305,7 +378,7 @@ void QItemModelBarDataProxy::setRowCategories(const QStringList &categories) { if (dptr()->m_rowCategories != categories) { dptr()->m_rowCategories = categories; - emit rowCategoriesChanged(categories); + emit rowCategoriesChanged(); } } @@ -323,7 +396,7 @@ void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories) { if (dptr()->m_columnCategories != categories) { dptr()->m_columnCategories = categories; - emit columnCategoriesChanged(categories); + emit columnCategoriesChanged(); } } @@ -392,24 +465,26 @@ bool QItemModelBarDataProxy::autoColumnCategories() const } /*! - * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the - * mapping. + * Changes \a rowRole, \a columnRole, \a valueRole, \a rotationRole, + * \a rowCategories and \a columnCategories to the mapping. */ void QItemModelBarDataProxy::remap(const QString &rowRole, const QString &columnRole, const QString &valueRole, + const QString &rotationRole, const QStringList &rowCategories, const QStringList &columnCategories) { setRowRole(rowRole); setColumnRole(columnRole); setValueRole(valueRole); + setRotationRole(rotationRole); setRowCategories(rowCategories); setColumnCategories(columnCategories); } /*! - * /return index of the specified \a category in row categories list. + * \return index of the specified \a category in row categories list. * If the row categories list is empty, -1 is returned. * \note If the automatic row categories generation is in use, this method will * not return a valid index before the data in the model is resolved for the first time. @@ -420,7 +495,7 @@ int QItemModelBarDataProxy::rowCategoryIndex(const QString &category) } /*! - * /return index of the specified \a category in column categories list. + * \return index of the specified \a category in column categories list. * If the category is not found, -1 is returned. * \note If the automatic column categories generation is in use, this method will * not return a valid index before the data in the model is resolved for the first time. @@ -477,6 +552,8 @@ void QItemModelBarDataProxyPrivate::connectItemModelHandler() m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelBarDataProxy::rowCategoriesChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelBarDataProxy::columnCategoriesChanged, diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h index 4e62b4c3..f19b4445 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy.h +++ b/src/datavisualization/data/qitemmodelbardataproxy.h @@ -20,8 +20,7 @@ #define QITEMMODELBARDATAPROXY_H #include <QtDataVisualization/qbardataproxy.h> -#include <QAbstractItemModel> -#include <QStringList> +#include <QtCore/QAbstractItemModel> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -34,6 +33,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged) Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged) Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged) + Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged) Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories NOTIFY rowCategoriesChanged) Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories NOTIFY columnCategoriesChanged) Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged) @@ -50,8 +50,15 @@ public: QObject *parent = 0); QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, const QString &columnRole, const QString &valueRole, + const QString &rotationRole, QObject *parent = 0); + QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, + const QString &columnRole, const QString &valueRole, const QStringList &rowCategories, const QStringList &columnCategories, QObject *parent = 0); + QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, + const QString &columnRole, const QString &valueRole, + const QString &rotationRole, const QStringList &rowCategories, + const QStringList &columnCategories, QObject *parent = 0); virtual ~QItemModelBarDataProxy(); void setItemModel(const QAbstractItemModel *itemModel); @@ -63,6 +70,8 @@ public: QString columnRole() const; void setValueRole(const QString &role); QString valueRole() const; + void setRotationRole(const QString &role); + QString rotationRole() const; void setRowCategories(const QStringList &categories); QStringList rowCategories() const; @@ -77,7 +86,8 @@ public: bool autoColumnCategories() const; void remap(const QString &rowRole, const QString &columnRole, - const QString &valueRole, const QStringList &rowCategories, + const QString &valueRole, const QString &rotationRole, + const QStringList &rowCategories, const QStringList &columnCategories); Q_INVOKABLE int rowCategoryIndex(const QString& category); @@ -85,11 +95,12 @@ public: signals: void itemModelChanged(const QAbstractItemModel* itemModel); - void rowRoleChanged(QString role); - void columnRoleChanged(QString role); - void valueRoleChanged(QString role); - void rowCategoriesChanged(QStringList categories); - void columnCategoriesChanged(QStringList categories); + void rowRoleChanged(const QString &role); + void columnRoleChanged(const QString &role); + void valueRoleChanged(const QString &role); + void rotationRoleChanged(const QString &role); + void rowCategoriesChanged(); + void columnCategoriesChanged(); void useModelCategoriesChanged(bool enable); void autoRowCategoriesChanged(bool enable); void autoColumnCategoriesChanged(bool enable); diff --git a/src/datavisualization/data/qitemmodelbardataproxy_p.h b/src/datavisualization/data/qitemmodelbardataproxy_p.h index 0c987a00..2fd74bb2 100644 --- a/src/datavisualization/data/qitemmodelbardataproxy_p.h +++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h @@ -53,6 +53,7 @@ private: QString m_rowRole; QString m_columnRole; QString m_valueRole; + QString m_rotationRole; // For row/column items, sort items into these categories. Other categories are ignored. QStringList m_rowCategories; diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp index 1edee53c..a5287abc 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp @@ -18,7 +18,6 @@ #include "qitemmodelscatterdataproxy_p.h" #include "scatteritemmodelhandler_p.h" -#include <QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -93,6 +92,16 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty string ItemModelScatterDataProxy::rotationRole + * + * Defines the rotation role for the mapping. + * The model may supply the value for rotation as either variant that is directly convertible + * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first + * will construct the quaternion directly with given values, and the second one will construct + * the quaternion using QQuaternion::fromAxisAndAngle() method. + */ + +/*! * Constructs QItemModelScatterDataProxy with optional \a parent. */ QItemModelScatterDataProxy::QItemModelScatterDataProxy(QObject *parent) @@ -134,6 +143,28 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel } /*! + * Constructs QItemModelScatterDataProxy with \a itemModel and optional \a parent. Proxy doesn't take + * ownership of the \a itemModel, as typically item models are owned by other controls. + * The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, zPosRole property + * to \a zPosRole, and rotationRole property to \a rotationRole. + */ +QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, + const QString &xPosRole, + const QString &yPosRole, + const QString &zPosRole, + const QString &rotationRole, + QObject *parent) + : QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent) +{ + dptr()->m_itemModelHandler->setItemModel(itemModel); + dptr()->m_xPosRole = xPosRole; + dptr()->m_yPosRole = yPosRole; + dptr()->m_zPosRole = zPosRole; + dptr()->m_rotationRole = rotationRole; + dptr()->connectItemModelHandler(); +} + +/*! * Destroys QItemModelScatterDataProxy. */ QItemModelScatterDataProxy::~QItemModelScatterDataProxy() @@ -211,14 +242,38 @@ QString QItemModelScatterDataProxy::zPosRole() const } /*! - * Changes \a xPosRole, \a yPosRole and \a zPosRole mapping. + * \property QItemModelScatterDataProxy::rotationRole + * + * Defines the rotation role for the mapping. + * + * The model may supply the value for rotation as either variant that is directly convertible + * to QQuartenion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first + * will construct the quaternion directly with given values, and the second one will construct + * the quaternion using QQuaternion::fromAxisAndAngle() method. + */ +void QItemModelScatterDataProxy::setRotationRole(const QString &role) +{ + if (dptr()->m_rotationRole != role) { + dptr()->m_rotationRole = role; + emit rotationRoleChanged(role); + } +} + +QString QItemModelScatterDataProxy::rotationRole() const +{ + return dptrc()->m_rotationRole; +} + +/*! + * Changes \a xPosRole, \a yPosRole, \a zPosRole, and \a rotationRole mapping. */ void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole, - const QString &zPosRole) + const QString &zPosRole, const QString &rotationRole) { setXPosRole(xPosRole); setYPosRole(yPosRole); setZPosRole(zPosRole); + setRotationRole(rotationRole); } /*! diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h index 0f69afa7..c6d2245d 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h @@ -20,8 +20,8 @@ #define QITEMMODELSCATTERDATAPROXY_H #include <QtDataVisualization/qscatterdataproxy.h> -#include <QAbstractItemModel> -#include <QStringList> +#include <QtCore/QAbstractItemModel> +#include <QtCore/QString> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDa Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged) Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged) Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged) + Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged) public: explicit QItemModelScatterDataProxy(QObject *parent = 0); @@ -41,6 +42,10 @@ public: QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, QObject *parent = 0); + QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, + const QString &xPosRole, const QString &yPosRole, + const QString &zPosRole, const QString &rotationRole, + QObject *parent = 0); virtual ~QItemModelScatterDataProxy(); void setItemModel(const QAbstractItemModel *itemModel); @@ -52,14 +57,18 @@ public: QString yPosRole() const; void setZPosRole(const QString &role); QString zPosRole() const; + void setRotationRole(const QString &role); + QString rotationRole() const; - void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole); + void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, + const QString &rotationRole); signals: void itemModelChanged(const QAbstractItemModel* itemModel); - void xPosRoleChanged(QString role); - void yPosRoleChanged(QString role); - void zPosRoleChanged(QString role); + void xPosRoleChanged(const QString &role); + void yPosRoleChanged(const QString &role); + void zPosRoleChanged(const QString &role); + void rotationRoleChanged(const QString &role); protected: QItemModelScatterDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h index b8804c5c..4e1f321f 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h @@ -52,6 +52,7 @@ private: QString m_xPosRole; QString m_yPosRole; QString m_zPosRole; + QString m_rotationRole; friend class ScatterItemModelHandler; friend class QItemModelScatterDataProxy; diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp index 0c206b81..f15a8923 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp @@ -18,7 +18,6 @@ #include "qitemmodelsurfacedataproxy_p.h" #include "surfaceitemmodelhandler_p.h" -#include <QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -30,7 +29,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source * for Q3DSurface. It uses the defined mappings to map data from the model to rows, columns, and - * values of Q3DSurface graph. + * surface points of Q3DSurface graph. * * Data is resolved asynchronously whenever the mapping or the model changes. * QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved. @@ -39,8 +38,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * * 1) If useModelCategories property is set to true, this proxy will map rows and * columns of QAbstractItemModel to rows and columns of Q3DSurface, and uses the value returned for - * Qt::DisplayRole as bar value by default. - * The value role to be used can be redefined if Qt::DisplayRole is not suitable. + * Qt::DisplayRole as Y-position by default. Row and column headers are used for Z-position and + * X-position by default, if they can be converted to floats. Otherwise row and column indices + * are used. + * The Y-position role to be used can be redefined if Qt::DisplayRole is not suitable. + * The Z-position and X-position roles to be used can be redefined if the headers or indices + * are not suitable. * * 2) For models that do not have data already neatly sorted into rows and columns, such as * QAbstractListModel based models, you can define a role from the model to map for each of row, @@ -105,10 +108,18 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! - * \qmlproperty string ItemModelSurfaceDataProxy::valueRole - * The value role of the mapping. - * The value indicated by value role is set as Y-coodrinate value of the - * QSurfaceDataItem when model data is resolved. + * \qmlproperty string ItemModelSurfaceDataProxy::xPosRole + * The X position role of the mapping. + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::yPosRole + * The Y position role of the mapping. + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::zPosRole + * The Z position role of the mapping. */ /*! @@ -169,17 +180,17 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel /*! * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take * ownership of the \a itemModel, as typically item models are owned by other controls. - * The value role is set to \a valueRole. + * The yPosRole role is set to \a yPosRole. * This constructor is meant to be used with models that have data properly sorted * in rows and columns already, so it also sets useModelCategories property to true. */ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, - const QString &valueRole, + const QString &yPosRole, QObject *parent) : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent) { dptr()->m_itemModelHandler->setItemModel(itemModel); - dptr()->m_valueRole = valueRole; + dptr()->m_yPosRole = yPosRole; dptr()->m_useModelCategories = true; dptr()->connectItemModelHandler(); } @@ -187,33 +198,93 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel /*! * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take * ownership of the \a itemModel, as typically item models are owned by other controls. - * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole. + * The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole. + * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively. + */ +QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, + const QString &rowRole, + const QString &columnRole, + const QString &yPosRole, + QObject *parent) + : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent) +{ + dptr()->m_itemModelHandler->setItemModel(itemModel); + dptr()->m_rowRole = rowRole; + dptr()->m_columnRole = columnRole; + dptr()->m_xPosRole = columnRole; + dptr()->m_yPosRole = yPosRole; + dptr()->m_zPosRole = rowRole; + dptr()->connectItemModelHandler(); +} + +/*! + * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take + * ownership of the \a itemModel, as typically item models are owned by other controls. + * The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, and + * \a zPosRole. + */ +QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, + const QString &rowRole, + const QString &columnRole, + const QString &xPosRole, + const QString &yPosRole, + const QString &zPosRole, + QObject *parent) + : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent) +{ + dptr()->m_itemModelHandler->setItemModel(itemModel); + dptr()->m_rowRole = rowRole; + dptr()->m_columnRole = columnRole; + dptr()->m_xPosRole = xPosRole; + dptr()->m_yPosRole = yPosRole; + dptr()->m_zPosRole = zPosRole; + dptr()->connectItemModelHandler(); +} + +/*! + * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take + * ownership of the \a itemModel, as typically item models are owned by other controls. + * The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole. + * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively. + * Row and column categories are set with \a rowCategories and \a columnCategories. + * This constructor also sets autoRowCategories and autoColumnCategories to false. */ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, const QString &columnRole, - const QString &valueRole, + const QString &yPosRole, + const QStringList &rowCategories, + const QStringList &columnCategories, QObject *parent) : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent) { dptr()->m_itemModelHandler->setItemModel(itemModel); dptr()->m_rowRole = rowRole; dptr()->m_columnRole = columnRole; - dptr()->m_valueRole = valueRole; + dptr()->m_xPosRole = columnRole; + dptr()->m_yPosRole = yPosRole; + dptr()->m_zPosRole = rowRole; + dptr()->m_rowCategories = rowCategories; + dptr()->m_columnCategories = columnCategories; + dptr()->m_autoRowCategories = false; + dptr()->m_autoColumnCategories = false; dptr()->connectItemModelHandler(); } /*! * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take * ownership of the \a itemModel, as typically item models are owned by other controls. - * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole. + * The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, + * and \a zPosRole. * Row and column categories are set with \a rowCategories and \a columnCategories. * This constructor also sets autoRowCategories and autoColumnCategories to false. */ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, const QString &columnRole, - const QString &valueRole, + const QString &xPosRole, + const QString &yPosRole, + const QString &zPosRole, const QStringList &rowCategories, const QStringList &columnCategories, QObject *parent) @@ -222,7 +293,9 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel dptr()->m_itemModelHandler->setItemModel(itemModel); dptr()->m_rowRole = rowRole; dptr()->m_columnRole = columnRole; - dptr()->m_valueRole = valueRole; + dptr()->m_xPosRole = xPosRole; + dptr()->m_yPosRole = yPosRole; + dptr()->m_zPosRole = zPosRole; dptr()->m_rowCategories = rowCategories; dptr()->m_columnCategories = columnCategories; dptr()->m_autoRowCategories = false; @@ -290,21 +363,57 @@ QString QItemModelSurfaceDataProxy::columnRole() const } /*! - * \property QItemModelSurfaceDataProxy::valueRole + * \property QItemModelSurfaceDataProxy::xPosRole + * + * Defines the X position role for the mapping. + */ +void QItemModelSurfaceDataProxy::setXPosRole(const QString &role) +{ + if (dptr()->m_xPosRole != role) { + dptr()->m_xPosRole = role; + emit xPosRoleChanged(role); + } +} + +QString QItemModelSurfaceDataProxy::xPosRole() const +{ + return dptrc()->m_xPosRole; +} + +/*! + * \property QItemModelSurfaceDataProxy::yPosRole * - * Defines the value role for the mapping. + * Defines the Y position role for the mapping. */ -void QItemModelSurfaceDataProxy::setValueRole(const QString &role) +void QItemModelSurfaceDataProxy::setYPosRole(const QString &role) { - if (dptr()->m_valueRole != role) { - dptr()->m_valueRole = role; - emit valueRoleChanged(role); + if (dptr()->m_yPosRole != role) { + dptr()->m_yPosRole = role; + emit yPosRoleChanged(role); } } -QString QItemModelSurfaceDataProxy::valueRole() const +QString QItemModelSurfaceDataProxy::yPosRole() const { - return dptrc()->m_valueRole; + return dptrc()->m_yPosRole; +} + +/*! + * \property QItemModelSurfaceDataProxy::zPosRole + * + * Defines the Z position role for the mapping. + */ +void QItemModelSurfaceDataProxy::setZPosRole(const QString &role) +{ + if (dptr()->m_zPosRole != role) { + dptr()->m_zPosRole = role; + emit zPosRoleChanged(role); + } +} + +QString QItemModelSurfaceDataProxy::zPosRole() const +{ + return dptrc()->m_zPosRole; } /*! @@ -316,7 +425,7 @@ void QItemModelSurfaceDataProxy::setRowCategories(const QStringList &categories) { if (dptr()->m_rowCategories != categories) { dptr()->m_rowCategories = categories; - emit rowCategoriesChanged(categories); + emit rowCategoriesChanged(); } } @@ -334,7 +443,7 @@ void QItemModelSurfaceDataProxy::setColumnCategories(const QStringList &categori { if (dptr()->m_columnCategories != categories) { dptr()->m_columnCategories = categories; - emit columnCategoriesChanged(categories); + emit columnCategoriesChanged(); } } @@ -403,24 +512,28 @@ bool QItemModelSurfaceDataProxy::autoColumnCategories() const } /*! - * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the - * mapping. + * Changes \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, \a zPosRole, + * \a rowCategories and \a columnCategories to the mapping. */ void QItemModelSurfaceDataProxy::remap(const QString &rowRole, const QString &columnRole, - const QString &valueRole, + const QString &xPosRole, + const QString &yPosRole, + const QString &zPosRole, const QStringList &rowCategories, const QStringList &columnCategories) { setRowRole(rowRole); setColumnRole(columnRole); - setValueRole(valueRole); + setXPosRole(xPosRole); + setYPosRole(yPosRole); + setZPosRole(zPosRole); setRowCategories(rowCategories); setColumnCategories(columnCategories); } /*! - * /return index of the specified \a category in row categories list. + * \return index of the specified \a category in row categories list. * If the row categories list is empty, -1 is returned. * \note If the automatic row categories generation is in use, this method will * not return a valid index before the data in the model is resolved for the first time. @@ -431,7 +544,7 @@ int QItemModelSurfaceDataProxy::rowCategoryIndex(const QString &category) } /*! - * /return index of the specified \a category in column categories list. + * \return index of the specified \a category in column categories list. * If the category is not found, -1 is returned. * \note If the automatic column categories generation is in use, this method will * not return a valid index before the data in the model is resolved for the first time. @@ -486,7 +599,11 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler() m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRoleChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); - QObject::connect(qptr(), &QItemModelSurfaceDataProxy::valueRoleChanged, + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRoleChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRoleChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowCategoriesChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h index d1e0f2b8..b1ebbeed 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h @@ -20,8 +20,8 @@ #define QITEMMODELSURFACEDATAPROXY_H #include <QtDataVisualization/qsurfacedataproxy.h> -#include <QAbstractItemModel> -#include <QStringList> +#include <QtCore/QAbstractItemModel> +#include <QtCore/QStringList> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -33,7 +33,9 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged) Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged) Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged) - Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged) + Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged) + Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged) + Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged) Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories NOTIFY rowCategoriesChanged) Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories NOTIFY columnCategoriesChanged) Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged) @@ -43,13 +45,22 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa public: explicit QItemModelSurfaceDataProxy(QObject *parent = 0); QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0); - QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &valueRole, + QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &yPosRole, QObject *parent = 0); QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, - const QString &columnRole, const QString &valueRole, + const QString &columnRole, const QString &yPosRole, QObject *parent = 0); QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, - const QString &columnRole, const QString &valueRole, + const QString &columnRole, const QString &xPosRole, + const QString &yPosRole, const QString &zPosRole, + QObject *parent = 0); + QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, + const QString &columnRole, const QString &yPosRole, + const QStringList &rowCategories, const QStringList &columnCategories, + QObject *parent = 0); + QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole, + const QString &columnRole, const QString &xPosRole, + const QString &yPosRole, const QString &zPosRole, const QStringList &rowCategories, const QStringList &columnCategories, QObject *parent = 0); virtual ~QItemModelSurfaceDataProxy(); @@ -61,8 +72,12 @@ public: QString rowRole() const; void setColumnRole(const QString &role); QString columnRole() const; - void setValueRole(const QString &role); - QString valueRole() const; + void setXPosRole(const QString &role); + QString xPosRole() const; + void setYPosRole(const QString &role); + QString yPosRole() const; + void setZPosRole(const QString &role); + QString zPosRole() const; void setRowCategories(const QStringList &categories); QStringList rowCategories() const; @@ -77,7 +92,8 @@ public: bool autoColumnCategories() const; void remap(const QString &rowRole, const QString &columnRole, - const QString &valueRole, const QStringList &rowCategories, + const QString &xPosRole, const QString &yPosRole, + const QString &zPosRole, const QStringList &rowCategories, const QStringList &columnCategories); Q_INVOKABLE int rowCategoryIndex(const QString& category); @@ -85,11 +101,13 @@ public: signals: void itemModelChanged(const QAbstractItemModel* itemModel); - void rowRoleChanged(QString role); - void columnRoleChanged(QString role); - void valueRoleChanged(QString role); - void rowCategoriesChanged(QStringList categories); - void columnCategoriesChanged(QStringList categories); + void rowRoleChanged(const QString &role); + void columnRoleChanged(const QString &role); + void xPosRoleChanged(const QString &role); + void yPosRoleChanged(const QString &role); + void zPosRoleChanged(const QString &role); + void rowCategoriesChanged(); + void columnCategoriesChanged(); void useModelCategoriesChanged(bool enable); void autoRowCategoriesChanged(bool enable); void autoColumnCategoriesChanged(bool enable); diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h index 5049a25e..0aaea8fd 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h @@ -52,7 +52,9 @@ private: QString m_rowRole; QString m_columnRole; - QString m_valueRole; + QString m_xPosRole; + QString m_yPosRole; + QString m_zPosRole; // For row/column items, sort items into these categories. Other categories are ignored. QStringList m_rowCategories; diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp index 33f8bed0..9751dfeb 100644 --- a/src/datavisualization/data/qscatterdataitem.cpp +++ b/src/datavisualization/data/qscatterdataitem.cpp @@ -52,6 +52,16 @@ QScatterDataItem::QScatterDataItem(const QVector3D &position) } /*! + * Constructs QScatterDataItem with \a position and \a rotation. + */ +QScatterDataItem::QScatterDataItem(const QVector3D &position, const QQuaternion &rotation) + : d_ptr(0), + m_position(position), + m_rotation(rotation) +{ +} + +/*! * Constructs a copy of \a other. */ QScatterDataItem::QScatterDataItem(const QScatterDataItem &other) diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h index d2ef3bcc..87cc1fc5 100644 --- a/src/datavisualization/data/qscatterdataitem.h +++ b/src/datavisualization/data/qscatterdataitem.h @@ -20,9 +20,7 @@ #define QSCATTERDATAITEM_H #include <QtDataVisualization/qdatavisualizationglobal.h> - -#include <QVector3D> -#include <QQuaternion> +#include <QtGui/QQuaternion> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -33,6 +31,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatterDataItem public: QScatterDataItem(); QScatterDataItem(const QVector3D &position); + QScatterDataItem(const QVector3D &position, const QQuaternion &rotation); QScatterDataItem(const QScatterDataItem &other); ~QScatterDataItem(); @@ -50,7 +49,7 @@ public: inline float z() const { return m_position.z(); } protected: - virtual void createExtraData(); + void createExtraData(); QScatterDataItemPrivate *d_ptr; diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp index b5e3863d..dbbb4384 100644 --- a/src/datavisualization/data/qscatterdataproxy.cpp +++ b/src/datavisualization/data/qscatterdataproxy.cpp @@ -98,7 +98,7 @@ QScatterDataProxy::~QScatterDataProxy() * * The series this proxy is attached to. */ -QScatter3DSeries *QScatterDataProxy::series() +QScatter3DSeries *QScatterDataProxy::series() const { return static_cast<QScatter3DSeries *>(d_ptr->series()); } diff --git a/src/datavisualization/data/qscatterdataproxy.h b/src/datavisualization/data/qscatterdataproxy.h index b8179166..fe561bbd 100644 --- a/src/datavisualization/data/qscatterdataproxy.h +++ b/src/datavisualization/data/qscatterdataproxy.h @@ -43,7 +43,7 @@ public: explicit QScatterDataProxy(QObject *parent = 0); virtual ~QScatterDataProxy(); - QScatter3DSeries *series(); + QScatter3DSeries *series() const; int itemCount() const; const QScatterDataArray *array() const; const QScatterDataItem *itemAt(int index) const; diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp index e5f06cc6..b7e15014 100644 --- a/src/datavisualization/data/qsurface3dseries.cpp +++ b/src/datavisualization/data/qsurface3dseries.cpp @@ -221,7 +221,7 @@ void QSurface3DSeries::setSelectedPoint(const QPoint &position) { // Don't do this in private to avoid loops, as that is used for callback from controller. if (d_ptr->m_controller) - static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this); + static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this, true); else dptr()->setSelectedPoint(position); } diff --git a/src/datavisualization/data/qsurface3dseries.h b/src/datavisualization/data/qsurface3dseries.h index b8a1a62b..8347104e 100644 --- a/src/datavisualization/data/qsurface3dseries.h +++ b/src/datavisualization/data/qsurface3dseries.h @@ -65,7 +65,7 @@ public: signals: void dataProxyChanged(QSurfaceDataProxy *proxy); - void selectedPointChanged(QPoint position); + void selectedPointChanged(const QPoint &position); void flatShadingEnabledChanged(bool enable); void flatShadingSupportedChanged(bool enable); void drawModeChanged(QSurface3DSeries::DrawFlags mode); diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h index f305952b..1e4a384d 100644 --- a/src/datavisualization/data/qsurfacedataitem.h +++ b/src/datavisualization/data/qsurfacedataitem.h @@ -20,8 +20,7 @@ #define QSURFACEDATAITEM_H #include <QtDataVisualization/qdatavisualizationglobal.h> - -#include <QVector3D> +#include <QtGui/QVector3D> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -47,7 +46,7 @@ public: inline float z() const { return m_position.z(); } protected: - virtual void createExtraData(); + void createExtraData(); QSurfaceDataItemPrivate *d_ptr; diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index 43ce40eb..34cea326 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -131,7 +131,7 @@ QSurfaceDataProxy::~QSurfaceDataProxy() * * The series this proxy is attached to. */ -QSurface3DSeries *QSurfaceDataProxy::series() +QSurface3DSeries *QSurfaceDataProxy::series() const { return static_cast<QSurface3DSeries *>(d_ptr->series()); } @@ -186,6 +186,15 @@ void QSurfaceDataProxy::setItem(int rowIndex, int columnIndex, const QSurfaceDat } /*! + * Changes a single item at \a position to the \a item. + * The X-value of \a position indicates the row and the Y-value indicates the column. + */ +void QSurfaceDataProxy::setItem(const QPoint &position, const QSurfaceDataItem &item) +{ + setItem(position.x(), position.y(), item); +} + +/*! * Adds a new \a row to the end of array. The new \a row must have * the same number of columns as the rows at the initial array. * @@ -259,6 +268,29 @@ const QSurfaceDataArray *QSurfaceDataProxy::array() const } /*! + * \return pointer to the item at \a rowIndex, \a columnIndex. It is guaranteed to be valid only + * until the next call that modifies data. + */ +const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int rowIndex, int columnIndex) const +{ + const QSurfaceDataArray &dataArray = *dptrc()->m_dataArray; + Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size()); + const QSurfaceDataRow &dataRow = *dataArray[rowIndex]; + Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size()); + return &dataRow.at(columnIndex); +} + +/*! + * \return pointer to the item at \a position. The X-value of \a position indicates the row + * and the Y-value indicates the column. The item is guaranteed to be valid only + * until the next call that modifies data. + */ +const QSurfaceDataItem *QSurfaceDataProxy::itemAt(const QPoint &position) const +{ + return itemAt(position.x(), position.y()); +} + +/*! * \property QSurfaceDataProxy::rowCount * * \return number of rows in the data. @@ -282,15 +314,6 @@ int QSurfaceDataProxy::columnCount() const } /*! - * \return pointer to the item at \a index. It is guaranteed to be valid only until the next call that - * modifies data. - */ -const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int index) const -{ - return &dptrc()->m_dataArray->at(index)->at(2); -} - -/*! * \internal */ QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptr() diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h index 0933faf6..475f1f2d 100644 --- a/src/datavisualization/data/qsurfacedataproxy.h +++ b/src/datavisualization/data/qsurfacedataproxy.h @@ -45,11 +45,12 @@ public: explicit QSurfaceDataProxy(QObject *parent = 0); virtual ~QSurfaceDataProxy(); - QSurface3DSeries *series(); + QSurface3DSeries *series() const; int rowCount() const; int columnCount() const; const QSurfaceDataArray *array() const; - const QSurfaceDataItem *itemAt(int index) const; + const QSurfaceDataItem *itemAt(int rowIndex, int columnIndex) const; + const QSurfaceDataItem *itemAt(const QPoint &position) const; void resetArray(QSurfaceDataArray *newArray); @@ -57,6 +58,7 @@ public: void setRows(int rowIndex, const QSurfaceDataArray &rows); void setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item); + void setItem(const QPoint &position, const QSurfaceDataItem &item); int addRow(QSurfaceDataRow *row); int addRows(const QSurfaceDataArray &rows); diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h index 658abe32..7c3486d2 100644 --- a/src/datavisualization/data/qsurfacedataproxy_p.h +++ b/src/datavisualization/data/qsurfacedataproxy_p.h @@ -32,8 +32,6 @@ #include "qsurfacedataproxy.h" #include "qabstractdataproxy_p.h" -#include <QSize> - QT_BEGIN_NAMESPACE_DATAVISUALIZATION class QSurfaceDataProxyPrivate : public QAbstractDataProxyPrivate diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp index 1c936d08..08ed12f3 100644 --- a/src/datavisualization/data/scatteritemmodelhandler.cpp +++ b/src/datavisualization/data/scatteritemmodelhandler.cpp @@ -17,7 +17,6 @@ ****************************************************************************/ #include "scatteritemmodelhandler_p.h" -#include <QTimer> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -92,6 +91,41 @@ void ScatterItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int s } } +static inline QQuaternion toQuaternion(const QVariant &variant) +{ + if (variant.canConvert<QQuaternion>()) { + return variant.value<QQuaternion>(); + } else if (variant.canConvert<QString>()) { + QString s = variant.toString(); + if (!s.isEmpty()) { + bool angleAndAxis = false; + if (s.startsWith(QLatin1Char('@'))) { + angleAndAxis = true; + s = s.mid(1); + } + if (s.count(QLatin1Char(',')) == 3) { + int index = s.indexOf(QLatin1Char(',')); + int index2 = s.indexOf(QLatin1Char(','), index + 1); + int index3 = s.indexOf(QLatin1Char(','), index2 + 1); + + bool sGood, xGood, yGood, zGood; + float sCoord = s.left(index).toFloat(&sGood); + float xCoord = s.mid(index + 1, index2 - index - 1).toFloat(&xGood); + float yCoord = s.mid(index2 + 1, index3 - index2 - 1).toFloat(&yGood); + float zCoord = s.mid(index3 + 1).toFloat(&zGood); + + if (sGood && xGood && yGood && zGood) { + if (angleAndAxis) + return QQuaternion::fromAxisAndAngle(xCoord, yCoord, zCoord, sCoord); + else + return QQuaternion(sCoord, xCoord, yCoord, zCoord); + } + } + } + } + return QQuaternion(); +} + void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn, QScatterDataItem &item) { @@ -105,6 +139,8 @@ void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColum yPos = index.data(m_yPosRole).toFloat(); if (m_zPosRole != noRoleIndex) zPos = index.data(m_zPosRole).toFloat(); + if (m_rotationRole != noRoleIndex) + item.setRotation(toQuaternion(index.data(m_rotationRole))); item.setPosition(QVector3D(xPos, yPos, zPos)); } @@ -121,6 +157,7 @@ void ScatterItemModelHandler::resolveModel() m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex); m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), noRoleIndex); m_zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex); + m_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex); const int columnCount = m_itemModel->columnCount(); const int rowCount = m_itemModel->rowCount(); const int totalCount = rowCount * columnCount; diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h index f0e4fa84..0661d734 100644 --- a/src/datavisualization/data/scatteritemmodelhandler_p.h +++ b/src/datavisualization/data/scatteritemmodelhandler_p.h @@ -58,6 +58,7 @@ private: int m_xPosRole; int m_yPosRole; int m_zPosRole; + int m_rotationRole; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp index d39af816..3b2e64c5 100644 --- a/src/datavisualization/data/scatterrenderitem.cpp +++ b/src/datavisualization/data/scatterrenderitem.cpp @@ -33,7 +33,6 @@ ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other) m_visible(false) { m_position = other.m_position; - m_rotation = other.m_rotation; } ScatterRenderItem::~ScatterRenderItem() diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h index 45066dd8..eb070682 100644 --- a/src/datavisualization/data/scatterrenderitem_p.h +++ b/src/datavisualization/data/scatterrenderitem_p.h @@ -45,19 +45,8 @@ public: inline const QVector3D &position() const { return m_position; } inline void setPosition(const QVector3D &pos) { - if (m_position != pos) { + if (m_position != pos) m_position = pos; - // Force reformatting on next access by setting label string to null string - if (!m_selectionLabel.isNull()) - setSelectionLabel(QString()); - } - } - - inline QQuaternion rotation() const { return m_rotation; } - inline void setRotation(const QQuaternion &rotation) - { - if (m_rotation != rotation) - m_rotation = rotation; } inline bool isVisible() const { return m_visible; } @@ -65,7 +54,6 @@ public: protected: QVector3D m_position; - QQuaternion m_rotation; bool m_visible; friend class QScatterDataItem; diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp index 767425e9..f4383dbf 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler.cpp +++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp @@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +static const int noRoleIndex = -1; + SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent) : AbstractItemModelHandler(parent), m_proxy(proxy), @@ -50,7 +52,9 @@ void SurfaceItemModelHandler::resolveModel() QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); // Default to display role if no mapping - int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole); + int xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex); + int yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), Qt::DisplayRole); + int zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex); int rowCount = m_itemModel->rowCount(); int columnCount = m_itemModel->columnCount(); @@ -66,15 +70,41 @@ void SurfaceItemModelHandler::resolveModel() for (int i = 0; i < rowCount; i++) { QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnCount; j++) { + float xPos = j; + float zPos = i; + if (xPosRole != noRoleIndex) { + xPos = m_itemModel->index(i, j).data(xPosRole).toFloat(); + } else { + QString header = m_itemModel->headerData(j, Qt::Horizontal).toString(); + bool ok = false; + float headerValue = header.toFloat(&ok); + if (ok) + xPos = headerValue; + } + + if (zPosRole != noRoleIndex) { + zPos = m_itemModel->index(i, j).data(zPosRole).toFloat(); + } else { + QString header = m_itemModel->headerData(i, Qt::Vertical).toString(); + bool ok = false; + float headerValue = header.toFloat(&ok); + if (ok) + zPos = headerValue; + } + newProxyRow[j].setPosition( - QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(), - m_itemModel->index(i, j).data(valueRole).toFloat(), - m_itemModel->headerData(i, Qt::Vertical).toFloat())); + QVector3D(xPos, + m_itemModel->index(i, j).data(yPosRole).toFloat(), + zPos)); } } } else { int rowRole = roleHash.key(m_proxy->rowRole().toLatin1()); int columnRole = roleHash.key(m_proxy->columnRole().toLatin1()); + if (xPosRole == noRoleIndex) + xPosRole = columnRole; + if (zPosRole == noRoleIndex) + zPosRole = rowRole; bool generateRows = m_proxy->autoRowCategories(); bool generateColumns = m_proxy->autoColumnCategories(); @@ -87,14 +117,17 @@ void SurfaceItemModelHandler::resolveModel() QHash<QString, bool> columnListHash; // Sort values into rows and columns - typedef QHash<QString, float> ColumnValueMap; + typedef QHash<QString, QVector3D> ColumnValueMap; QHash <QString, ColumnValueMap> itemValueMap; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { QModelIndex index = m_itemModel->index(i, j); QString rowRoleStr = index.data(rowRole).toString(); QString columnRoleStr = index.data(columnRole).toString(); - itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal(); + QVector3D itemPos(index.data(xPosRole).toReal(), + index.data(yPosRole).toReal(), + index.data(zPosRole).toReal()); + itemValueMap[rowRoleStr][columnRoleStr] = itemPos; if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); rowList << rowRoleStr; @@ -128,11 +161,8 @@ void SurfaceItemModelHandler::resolveModel() for (int i = 0; i < rowList.size(); i++) { QString rowKey = rowList.at(i); QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); - for (int j = 0; j < columnList.size(); j++) { - newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(), - itemValueMap[rowKey][columnList.at(j)], - rowList.at(i).toFloat())); - } + for (int j = 0; j < columnList.size(); j++) + newProxyRow[j].setPosition(itemValueMap[rowKey][columnList.at(j)]); } } |