summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-12 14:26:41 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-08-13 07:43:29 +0300
commit018b9855f394271fa20f3e65fc1ca71c90f32384 (patch)
tree03314821a6808a26555f4ba01c8c91bc5e4b5662
parentd67c87ec3deb99d52eaa71d1272d72ae77da6216 (diff)
Add some missing data manipulation methods to bar proxy
+ Related widget example changes + Changed shadow perspective to get rid of some artifacts + Accessor for sample space size Change-Id: I7c4d7038479b65016209624d8e2ea77794210005 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
-rw-r--r--examples/widget/chart.cpp61
-rw-r--r--examples/widget/chart.h5
-rw-r--r--examples/widget/main.cpp40
-rw-r--r--src/datavis3d/data/qbardataproxy.cpp70
-rw-r--r--src/datavis3d/data/qbardataproxy.h42
-rw-r--r--src/datavis3d/data/qbardataproxy_p.h3
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp12
-rw-r--r--src/datavis3d/engine/bars3dcontroller_p.h1
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp2
-rw-r--r--src/datavis3d/engine/q3dbars.cpp5
-rw-r--r--src/datavis3d/engine/q3dbars.h1
11 files changed, 228 insertions, 14 deletions
diff --git a/examples/widget/chart.cpp b/examples/widget/chart.cpp
index d1038839..bd282b44 100644
--- a/examples/widget/chart.cpp
+++ b/examples/widget/chart.cpp
@@ -208,6 +208,67 @@ void ChartModifier::addRows()
qDebug() << "Added" << m_rowCount << "rows, time:" << timer.elapsed();
}
+void ChartModifier::changeItem()
+{
+ // TODO fix to use actual selected item, for now just assume some row/column are selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int column = qMin(4, (m_chart->dataProxy()->rowAt(row)->size() - 1));
+ if (column >= 0) {
+ QBarDataItem *item = new QBarDataItem();
+ item->setValue(qreal(rand() % 100));
+ m_chart->dataProxy()->setItem(row, column, item);
+ }
+ }
+}
+
+void ChartModifier::changeRow()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->dataProxy()->rowAt(row)->size());
+ for (int i = 0; i < newRow->size(); i++)
+ (*newRow)[i].setValue(qreal(rand() % 100));
+ m_chart->dataProxy()->setRow(row, newRow);
+ }
+}
+
+void ChartModifier::changeRows()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ QBarDataArray *newArray = new QBarDataArray;
+ for (int i = startRow; i <= row; i++ ) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->dataProxy()->rowAt(i)->size());
+ for (int j = 0; j < newRow->size(); j++)
+ (*newRow)[j].setValue(qreal(rand() % 100));
+ newArray->append(newRow);
+ }
+ m_chart->dataProxy()->setRows(startRow, newArray);
+ }
+}
+
+void ChartModifier::removeRow()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0)
+ m_chart->dataProxy()->removeRows(row, 1);
+}
+
+void ChartModifier::removeRows()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ m_chart->dataProxy()->removeRows(startRow, 3);
+ }
+}
+
void ChartModifier::changeStyle()
{
static int model = 0;
diff --git a/examples/widget/chart.h b/examples/widget/chart.h
index e42257ce..c4f21d7d 100644
--- a/examples/widget/chart.h
+++ b/examples/widget/chart.h
@@ -59,6 +59,11 @@ public:
void addDataSet();
void addRow();
void addRows();
+ void changeItem();
+ void changeRow();
+ void changeRows();
+ void removeRow();
+ void removeRows();
void changeStyle();
void changePresetCamera();
void changeTheme();
diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp
index 9614cc0f..1c537de5 100644
--- a/examples/widget/main.cpp
+++ b/examples/widget/main.cpp
@@ -82,6 +82,26 @@ int main(int argc, char **argv)
multiDataButton->setText(QStringLiteral("Insert many rows of data"));
multiDataButton->setEnabled(false);
+ QPushButton *changeSingleDataButton = new QPushButton(widget);
+ changeSingleDataButton->setText(QStringLiteral("Change selected bar value"));
+ changeSingleDataButton->setEnabled(false);
+
+ QPushButton *changeRowButton = new QPushButton(widget);
+ changeRowButton->setText(QStringLiteral("Change selected row values"));
+ changeRowButton->setEnabled(false);
+
+ QPushButton *changeRowsButton = new QPushButton(widget);
+ changeRowsButton->setText(QStringLiteral("Change three rows from selected"));
+ changeRowsButton->setEnabled(false);
+
+ QPushButton *removeRowButton = new QPushButton(widget);
+ removeRowButton->setText(QStringLiteral("Remove selected row"));
+ removeRowButton->setEnabled(false);
+
+ QPushButton *removeRowsButton = new QPushButton(widget);
+ removeRowsButton->setText(QStringLiteral("remove three rows from selected"));
+ removeRowsButton->setEnabled(false);
+
QPushButton *themeButton = new QPushButton(widget);
themeButton->setText(QStringLiteral("Change theme"));
@@ -190,6 +210,11 @@ int main(int argc, char **argv)
vLayout->addWidget(sampleSliderZ, 1, Qt::AlignTop);
vLayout->addWidget(dataButton, 0, Qt::AlignTop);
vLayout->addWidget(multiDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeSingleDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeRowButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeRowsButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeRowButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeRowsButton, 0, Qt::AlignTop);
vLayout->addWidget(themeButton, 0, Qt::AlignTop);
vLayout->addWidget(labelButton, 0, Qt::AlignTop);
vLayout->addWidget(styleButton, 0, Qt::AlignTop);
@@ -243,6 +268,11 @@ int main(int argc, char **argv)
&ChartModifier::changeTransparency);
QObject::connect(dataButton, &QPushButton::clicked, modifier, &ChartModifier::addRow);
QObject::connect(multiDataButton, &QPushButton::clicked, modifier, &ChartModifier::addRows);
+ QObject::connect(changeSingleDataButton, &QPushButton::clicked, modifier, &ChartModifier::changeItem);
+ QObject::connect(changeRowButton, &QPushButton::clicked, modifier, &ChartModifier::changeRow);
+ QObject::connect(changeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::changeRows);
+ QObject::connect(removeRowButton, &QPushButton::clicked, modifier, &ChartModifier::removeRow);
+ QObject::connect(removeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::removeRows);
QObject::connect(selectionButton, &QPushButton::clicked, modifier,
&ChartModifier::changeSelectionMode);
@@ -267,6 +297,16 @@ int main(int argc, char **argv)
&QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, multiDataButton,
&QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeSingleDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowsButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowsButton,
+ &QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderX,
&QSlider::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderZ,
diff --git a/src/datavis3d/data/qbardataproxy.cpp b/src/datavis3d/data/qbardataproxy.cpp
index f27e3407..651551cc 100644
--- a/src/datavis3d/data/qbardataproxy.cpp
+++ b/src/datavis3d/data/qbardataproxy.cpp
@@ -71,6 +71,19 @@ void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row)
emit rowsChanged(rowIndex, 1);
}
+void QBarDataProxy::setRows(int rowIndex, QBarDataArray *rows)
+{
+ int count = rows->size();
+ dptr()->setRows(rowIndex, rows);
+ emit rowsChanged(rowIndex, count);
+}
+
+void QBarDataProxy::setItem(int rowIndex, int columnIndex, QBarDataItem *item)
+{
+ dptr()->setItem(rowIndex, columnIndex, item);
+ emit itemChanged(rowIndex, columnIndex);
+}
+
int QBarDataProxy::addRow(QBarDataRow *row)
{
int addIndex = dptr()->addRow(row);
@@ -99,6 +112,14 @@ void QBarDataProxy::insertRows(int rowIndex, QBarDataArray *rows)
emit rowsInserted(rowIndex, insertCount);
}
+void QBarDataProxy::removeRows(int rowIndex, int removeCount)
+{
+ if (rowIndex < rowCount()) {
+ dptr()->removeRows(rowIndex, removeCount);
+ emit rowsRemoved(rowIndex, removeCount);
+ }
+}
+
// Mutexing data accessors should be done by user, if needed
int QBarDataProxy::rowCount()
{
@@ -112,12 +133,18 @@ const QBarDataArray *QBarDataProxy::array() const
const QBarDataRow *QBarDataProxy::rowAt(int rowIndex) const
{
- return dptrc()->m_dataArray[rowIndex];
+ const QBarDataArray &dataArray = dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ return dataArray[rowIndex];
}
const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const
{
- return &dptrc()->m_dataArray[rowIndex]->at(columnIndex);
+ const QBarDataArray &dataArray = dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ const QBarDataRow &dataRow = *dataArray[rowIndex];
+ Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size());
+ return &dataRow.at(columnIndex);
}
QBarDataProxyPrivate *QBarDataProxy::dptr()
@@ -162,10 +189,33 @@ bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray)
void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row)
{
QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray.size());
clearRow(rowIndex);
m_dataArray[rowIndex] = row;
}
+void QBarDataProxyPrivate::setRows(int rowIndex, QBarDataArray *rows)
+{
+ QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0 && (rowIndex + rows->size()) <= m_dataArray.size());
+ for (int i = 0; i < rows->size(); i++) {
+ clearRow(rowIndex);
+ m_dataArray[rowIndex] = rows->at(i);
+ rowIndex++;
+ }
+ delete rows;
+}
+
+void QBarDataProxyPrivate::setItem(int rowIndex, int columnIndex, QBarDataItem *item)
+{
+ QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray.size());
+ QBarDataRow &row = *m_dataArray[rowIndex];
+ Q_ASSERT(columnIndex < row.size());
+ row[columnIndex] = *item;
+ delete item;
+}
+
int QBarDataProxyPrivate::addRow(QBarDataRow *row)
{
QMutexLocker locker(&m_mutex);
@@ -187,17 +237,31 @@ int QBarDataProxyPrivate::addRows(QBarDataArray *rows)
void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row)
{
QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray.size());
m_dataArray.insert(rowIndex, row);
}
void QBarDataProxyPrivate::insertRows(int rowIndex, QBarDataArray *rows)
{
QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray.size());
for (int i = 0; i < rows->size(); i++)
- m_dataArray.insert(rowIndex, rows->at(i));
+ m_dataArray.insert(rowIndex++, rows->at(i));
delete rows;
}
+void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount)
+{
+ QMutexLocker locker(&m_mutex);
+ Q_ASSERT(rowIndex >= 0);
+ int maxRemoveCount = m_dataArray.size() - rowIndex;
+ removeCount = qMin(removeCount, maxRemoveCount);
+ for (int i = 0; i < removeCount; i++) {
+ clearRow(rowIndex);
+ m_dataArray.removeAt(rowIndex);
+ }
+}
+
// Protected & private functions. Do not mutex as these are used from mutexed functions.
void QBarDataProxyPrivate::clearRow(int rowIndex)
diff --git a/src/datavis3d/data/qbardataproxy.h b/src/datavis3d/data/qbardataproxy.h
index 02b8376d..c3217483 100644
--- a/src/datavis3d/data/qbardataproxy.h
+++ b/src/datavis3d/data/qbardataproxy.h
@@ -77,7 +77,7 @@ public:
const QBarDataItem *itemAt(int rowIndex, int columnIndex) const; // Row and column in said row need to exist or this crashes
// The data array is a list of list (rows) of QBarDataItem instances.
- // Each row can contain different amount of items.
+ // Each row can contain different amount of items or even be null.
// All array/item manipulation functions are internally protected by data mutex.
@@ -88,33 +88,55 @@ public:
// TODO Should data manipulation/access methods be protected rather than public to enforce subclassing use of proxy?
// TODO Leaving them public gives user more options.
- // QBarDataProxy takes ownership of all QBarDataArrays, QBarDataRows, and QBarDataItems passed to it.
- // The pointers passed to it are not guaranteed to be valid after the calls.
+ // QBarDataProxy takes ownership of all QBarDataArrays, QBarDataRows, and QBarDataItems
+ // passed to it. The pointers passed to it are not guaranteed to be valid after the calls
+ // and should not be used to modify data further.
// Clears the existing array and sets it data to new array.
void resetArray(QBarDataArray *newArray);
+ // Change existing rows
void setRow(int rowIndex, QBarDataRow *row);
- // TODO? void setColumn(int columnIndex, QBarDataRow *column);
- // TODO void setItem(int rowIndex, int columnIndex, QBarDataItem *item);
+ void setRows(int rowIndex, QBarDataArray *rows);
+
+ // Setting a column is comparatively inefficient as it changes all rows.
+ // Can resize rows that are shorter than columnIndex.
+ // TODO void setColumn(int columnIndex, QBarDataRow *column);
+ // TODO void setColumns(int columnIndex, QBarDataArray *columns);
+
+ // Change single item
+ void setItem(int rowIndex, int columnIndex, QBarDataItem *item);
+ // Change block of items
+ // TODO setItems(int rowIndex, int columnIndex, QBarDataArray *items);
int addRow(QBarDataRow *row); // returns the index of added row
int addRows(QBarDataArray *rows); // returns the index of first added row
- // TODO? int addColumns(QBarDataArray *columns); // returns the index of first added column
+ // TODO int addColumn(QBarDataRow *column); // returns the index of the added column
+ // TODO int addColumns(QBarDataArray *columns); // returns the index of the first added column
+ // If rowIndex is equal to array size, rows are added to end of the array.
void insertRow(int rowIndex, QBarDataRow *row);
void insertRows(int rowIndex, QBarDataArray *rows);
- // TODO? void insertColumns(int columnIndex, QBarDataArray *columns);
+ // TODO void insertColumn(int columnIndex, QBarDataRow *column);
+ // TODO void insertColumns(int columnIndex, QBarDataArray *columns);
- // TODO void removeRows(int rowIndex, int removeCount);
- // TODO? void removeColumns(int columnIndex, int removeCount);
+ // Attempting to remove rows past the end of the array does nothing.
+ void removeRows(int rowIndex, int removeCount);
+ // TODO void removeColumns(int columnIndex, int removeCount);
signals:
void arrayReset();
void rowsAdded(int startIndex, int count);
void rowsChanged(int startIndex, int count);
- void rowsRemoved(int startIndex, int count); // Index may be over current array size if removed from end
+ // Index is the current array size if rows were removed from the end of the array
+ void rowsRemoved(int startIndex, int count);
void rowsInserted(int startIndex, int count);
+ // TODO void columnsChanged(int startIndex, int count);
+ // TODO void columnsAdded(int startIndex, int count);
+ // TODO void columnsRemoved(int startIndex, int count);
+ // TODO void columnsInserted(int startIndex, int count);
+ void itemChanged(int rowIndex, int columnIndex);
+ // TODO void itemsChanged(int rowIndex, int columnIndex, int rowCount, int columnCount);
protected:
QBarDataProxyPrivate *dptr();
diff --git a/src/datavis3d/data/qbardataproxy_p.h b/src/datavis3d/data/qbardataproxy_p.h
index c9dec1e4..2325a1c1 100644
--- a/src/datavis3d/data/qbardataproxy_p.h
+++ b/src/datavis3d/data/qbardataproxy_p.h
@@ -67,10 +67,13 @@ public:
bool resetArray(QBarDataArray *newArray);
void setRow(int rowIndex, QBarDataRow *row);
+ void setRows(int rowIndex, QBarDataArray *rows);
+ void setItem(int rowIndex, int columnIndex, QBarDataItem *item);
int addRow(QBarDataRow *row);
int addRows(QBarDataArray *rows);
void insertRow(int rowIndex, QBarDataRow *row);
void insertRows(int rowIndex, QBarDataArray *rows);
+ void removeRows(int rowIndex, int removeCount);
QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, int columnCount);
diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp
index 1c72b575..6eee2fcc 100644
--- a/src/datavis3d/engine/bars3dcontroller.cpp
+++ b/src/datavis3d/engine/bars3dcontroller.cpp
@@ -269,6 +269,7 @@ void Bars3dController::setDataProxy(QBarDataProxy *proxy)
QObject::connect(m_data, &QBarDataProxy::rowsChanged, this, &Bars3dController::handleRowsChanged);
QObject::connect(m_data, &QBarDataProxy::rowsRemoved, this, &Bars3dController::handleRowsRemoved);
QObject::connect(m_data, &QBarDataProxy::rowsInserted, this, &Bars3dController::handleRowsInserted);
+ QObject::connect(m_data, &QBarDataProxy::itemChanged, this, &Bars3dController::handleItemChanged);
adjustValueAxisRange();
m_valuesDirty = true;
@@ -330,6 +331,17 @@ void Bars3dController::handleRowsInserted(int startIndex, int count)
m_valuesDirty = true;
}
+void Bars3dController::handleItemChanged(int rowIndex, int columnIndex)
+{
+ Q_UNUSED(rowIndex)
+ Q_UNUSED(columnIndex)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_valuesDirty = true;
+}
+
void Bars3dController::handleAxisAutoAdjustRangeChanged(bool autoAdjust)
{
Q_UNUSED(autoAdjust)
diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h
index eeae402b..3fbf7383 100644
--- a/src/datavis3d/engine/bars3dcontroller_p.h
+++ b/src/datavis3d/engine/bars3dcontroller_p.h
@@ -180,6 +180,7 @@ public slots:
void handleRowsChanged(int startIndex, int count);
void handleRowsRemoved(int startIndex, int count);
void handleRowsInserted(int startIndex, int count);
+ void handleItemChanged(int rowIndex, int columnIndex);
virtual void handleAxisAutoAdjustRangeChanged(bool autoAdjust);
diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp
index 662e7c17..9340d556 100644
--- a/src/datavis3d/engine/bars3drenderer.cpp
+++ b/src/datavis3d/engine/bars3drenderer.cpp
@@ -617,7 +617,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// Set the depth projection matrix
#ifndef USE_WIDER_SHADOWS
// Use this for perspective shadows
- depthProjectionMatrix.perspective(15.0f, (GLfloat)m_mainViewPort.width()
+ depthProjectionMatrix.perspective(20.0f, (GLfloat)m_mainViewPort.width()
/ (GLfloat)m_mainViewPort.height(), 3.0f, 100.0f);
#else
// Use these for orthographic shadows
diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
index 33df8d2a..f7688530 100644
--- a/src/datavis3d/engine/q3dbars.cpp
+++ b/src/datavis3d/engine/q3dbars.cpp
@@ -250,6 +250,11 @@ void Q3DBars::setupSampleSpace(int samplesRow, int samplesColumn)
d_ptr->m_shared->setupSampleSpace(samplesRow, samplesColumn);
}
+QSize Q3DBars::sampleSpace()
+{
+ return QSize(d_ptr->m_shared->rowCount(), d_ptr->m_shared->columnCount());
+}
+
/*!
* \a preset Move camera to a predefined position from \c CameraPreset.
*
diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h
index a5284960..aea82b9e 100644
--- a/src/datavis3d/engine/q3dbars.h
+++ b/src/datavis3d/engine/q3dbars.h
@@ -85,6 +85,7 @@ public:
// how many samples per row and column, and names for axes
// TODO: This defines the data window, needs additional parameters startRow, startColumn
void setupSampleSpace(int samplesRow, int samplesColumn);
+ QSize sampleSpace(); // TODO: Return QRect once data window properly implemented?
// Select preset camera placement
void setCameraPreset(CameraPreset preset);