summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-23 13:57:47 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-24 09:50:51 +0300
commitf842e21c7fa44d806c06a1463c723632b10e6172 (patch)
tree544b03ec20521c203a884cf74809972410532730 /src/datavisualization/data
parentac789c99ad04e5e907365d408d5f94df1685a668 (diff)
Made surface axis ranges adjustable.
If the surface is partially off the visible range, only grids that are fully within the visible range will be drawn. If only one row or column is within visible range, surface is not drawn. Task-number: QTRD-2320 Change-Id: If2691577cde61dfd270d79c32b9d6f69984966ba Reviewed-by: Mika Salmela <mika.salmela@digia.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp101
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h4
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp3
3 files changed, 62 insertions, 46 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 293eb9eb..f40fa395 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -82,7 +82,7 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) :
* \sa heightMap
*/
QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent) :
- QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this, image), parent)
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
{
setHeightMap(image);
}
@@ -118,50 +118,17 @@ QHeightMapSurfaceDataProxy::~QHeightMapSurfaceDataProxy()
* grayscale images may improve data conversion speed for large images.
*
* Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ *
+ * The height map is resolved asynchronously. QSurfaceDataProxy::arrayReset() is emitted when the
+ * data has been resolved.
*/
void QHeightMapSurfaceDataProxy::setHeightMap(const QImage &image)
{
dptr()->m_heightMap = image;
- QImage heightImage = image;
- // Convert to RGB32 to be sure we're reading the right bytes
- if (heightImage.format() != QImage::Format_RGB32)
- heightImage = image.convertToFormat(QImage::Format_RGB32);
-
- uchar *bits = heightImage.bits();
-
- int imageHeight = heightImage.height();
- int imageWidth = heightImage.width();
- int bitCount = imageWidth * 4 * (imageHeight - 1);
- int widthBits = imageWidth * 4;
- qreal height = 0;
-
- QSurfaceDataArray *dataArray = new QSurfaceDataArray;
- dataArray->reserve(imageHeight);
- if (heightImage.isGrayscale()) {
- // Grayscale, it's enough to read Red byte
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
- for (int j = 0; j < imageWidth; j++)
- (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
- *dataArray << newRow;
- }
- } else {
- // Not grayscale, we'll need to calculate height from RGB
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
- for (int j = 0; j < imageWidth; j++) {
- int nextpixel = j * 4;
- height = (qreal(bits[bitCount + nextpixel])
- + qreal(bits[1 + bitCount + nextpixel])
- + qreal(bits[2 + bitCount + nextpixel]));
- (*newRow)[j] = (height / 3.0) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
- }
- *dataArray << newRow;
- }
- }
-
- resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth);
+ // We do resolving asynchronously to make qml onArrayReset handlers actually get the initial reset
+ if (!dptr()->m_resolveTimer.isActive())
+ dptr()->m_resolveTimer.start(0);
}
QImage QHeightMapSurfaceDataProxy::heightMap() const
@@ -210,17 +177,61 @@ const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() con
QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q)
: QSurfaceDataProxyPrivate(q)
{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout,
+ this, &QHeightMapSurfaceDataProxyPrivate::handlePendingResolve);
}
-QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q,
- const QImage &image)
- : QSurfaceDataProxyPrivate(q),
- m_heightMap(image)
+QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
{
}
-QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
+QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr()
{
+ return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr);
+}
+
+void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
+{
+ QImage heightImage = m_heightMap;
+ // Convert to RGB32 to be sure we're reading the right bytes
+ if (heightImage.format() != QImage::Format_RGB32)
+ heightImage = heightImage.convertToFormat(QImage::Format_RGB32);
+
+ uchar *bits = heightImage.bits();
+
+ int imageHeight = heightImage.height();
+ int imageWidth = heightImage.width();
+ int bitCount = imageWidth * 4 * (imageHeight - 1);
+ int widthBits = imageWidth * 4;
+ qreal height = 0;
+
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ dataArray->reserve(imageHeight);
+ if (heightImage.isGrayscale()) {
+ // Grayscale, it's enough to read Red byte
+ for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int j = 0; j < imageWidth; j++)
+ (*newRow)[j] = qreal(bits[bitCount + (j * 4)]) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
+ *dataArray << newRow;
+ }
+ } else {
+ // Not grayscale, we'll need to calculate height from RGB
+ for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int j = 0; j < imageWidth; j++) {
+ int nextpixel = j * 4;
+ height = (qreal(bits[bitCount + nextpixel])
+ + qreal(bits[1 + bitCount + nextpixel])
+ + qreal(bits[2 + bitCount + nextpixel]));
+ (*newRow)[j] = (height / 3.0) + 0.1; // Add 0.1 to raise it above ground to avoid glimmering at 0 height
+ }
+ *dataArray << newRow;
+ }
+ }
+
+ qptr()->resetArray(dataArray, 0.0, imageHeight, 0.0, imageWidth);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
index 3cccb4ed..7140c8ef 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
@@ -31,6 +31,7 @@
#include "qheightmapsurfacedataproxy.h"
#include "qsurfacedataproxy_p.h"
+#include <QTimer>
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
@@ -40,14 +41,15 @@ class QHeightMapSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate
public:
QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q);
- QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q, const QImage &image);
virtual ~QHeightMapSurfaceDataProxyPrivate();
private:
QHeightMapSurfaceDataProxy *qptr();
+ void handlePendingResolve();
QImage m_heightMap;
QString m_heightMapFile;
+ QTimer m_resolveTimer;
friend class QHeightMapSurfaceDataProxy;
};
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 30cc84f1..bd3688dc 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -39,6 +39,9 @@ const qreal defaultMaxValue = 10.0;
*
* All rows must have same number of values.
*
+ * \note Surfaces with less than two rows or columns are not considered valid surfaces and will
+ * not get rendered.
+ *
* QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
* \table
* \row