diff options
Diffstat (limited to 'src/datavisualization/engine/bars3dcontroller.cpp')
-rw-r--r-- | src/datavisualization/engine/bars3dcontroller.cpp | 269 |
1 files changed, 190 insertions, 79 deletions
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 5232a566..5bd37ccf 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,9 +19,9 @@ #include "bars3dcontroller_p.h" #include "bars3drenderer_p.h" #include "camerahelper_p.h" -#include "q3dabstractaxis_p.h" -#include "q3dvalueaxis_p.h" -#include "q3dcategoryaxis_p.h" +#include "qabstract3daxis_p.h" +#include "qvalue3daxis_p.h" +#include "qcategory3daxis_p.h" #include "qbardataproxy_p.h" #include "qbar3dseries_p.h" #include "thememanager_p.h" @@ -30,12 +30,14 @@ #include <QMatrix4x4> #include <qmath.h> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -Bars3DController::Bars3DController(QRect boundRect) - : Abstract3DController(boundRect), +Bars3DController::Bars3DController(QRect boundRect, Q3DScene *scene) + : Abstract3DController(boundRect, scene), m_selectedBar(invalidSelectionPosition()), m_selectedBarSeries(0), + m_primarySeries(0), + m_isMultiSeriesUniform(false), m_isBarSpecRelative(true), m_barThicknessRatio(1.0f), m_barSpacing(QSizeF(1.0, 1.0)), @@ -64,15 +66,16 @@ void Bars3DController::initializeOpenGL() setRenderer(m_renderer); synchDataToRenderer(); - QObject::connect(m_renderer, &Bars3DRenderer::barClicked, this, - &Bars3DController::handleBarClicked, Qt::QueuedConnection); emitNeedRender(); } void Bars3DController::synchDataToRenderer() { + if (!isInitialized()) + return; + // Background change requires reloading the meshes in bar graphs, so dirty the series visuals - if (m_themeManager->theme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { + if (m_themeManager->activeTheme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { m_isSeriesVisualsDirty = true; foreach (QAbstract3DSeries *series, m_seriesList) series->d_ptr->m_changeTracker.meshChanged = true; @@ -80,10 +83,12 @@ void Bars3DController::synchDataToRenderer() Abstract3DController::synchDataToRenderer(); - if (!isInitialized()) - return; - // Notify changes to renderer + if (m_changeTracker.multiSeriesScalingChanged) { + m_renderer->updateMultiSeriesScaling(m_isMultiSeriesUniform); + m_changeTracker.multiSeriesScalingChanged = false; + } + if (m_changeTracker.barSpecsChanged) { m_renderer->updateBarSpecs(m_barThicknessRatio, m_barSpacing, m_isBarSpecRelative); m_changeTracker.barSpecsChanged = false; @@ -98,8 +103,11 @@ void Bars3DController::synchDataToRenderer() void Bars3DController::handleArrayReset() { - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } // Clear selection unless still valid setSelectedBar(m_selectedBar, m_selectedBarSeries); emitNeedRender(); @@ -109,8 +117,11 @@ void Bars3DController::handleRowsAdded(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -118,8 +129,11 @@ void Bars3DController::handleRowsChanged(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -127,11 +141,25 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; - // Clear selection unless still valid - setSelectedBar(m_selectedBar, m_selectedBarSeries); + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series == m_selectedBarSeries) { + // If rows removed from selected series before the selection, adjust the selection + int selectedRow = m_selectedBar.x(); + if (startIndex <= selectedRow) { + if ((startIndex + count) > selectedRow) + selectedRow = -1; // Selected row removed + else + selectedRow -= count; // Move selected row down by amount of rows removed + + setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries); + } + } + + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -140,8 +168,21 @@ void Bars3DController::handleRowsInserted(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series == m_selectedBarSeries) { + // If rows inserted to selected series before the selection, adjust the selection + int selectedRow = m_selectedBar.x(); + if (startIndex <= selectedRow) { + selectedRow += count; + setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries); + } + } + + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } + emitNeedRender(); } @@ -149,50 +190,44 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) { Q_UNUSED(rowIndex) Q_UNUSED(columnIndex) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } void Bars3DController::handleDataRowLabelsChanged() { - QBar3DSeries *firstSeries = 0; - if (m_seriesList.size()) - firstSeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); - if (m_axisZ && firstSeries && firstSeries->dataProxy()) { + if (m_axisZ) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisZ->min()); int count = int(m_axisZ->max()) - min + 1; - QStringList subList = firstSeries->dataProxy()->rowLabels().mid(min, count); - static_cast<Q3DCategoryAxis *>(m_axisZ)->dptr()->setDataLabels(subList); + QStringList subList; + if (m_primarySeries && m_primarySeries->dataProxy()) + subList = m_primarySeries->dataProxy()->rowLabels().mid(min, count); + static_cast<QCategory3DAxis *>(m_axisZ)->dptr()->setDataLabels(subList); } } void Bars3DController::handleDataColumnLabelsChanged() { - QBar3DSeries *firstSeries = 0; - if (m_seriesList.size()) - firstSeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); - if (m_axisX && firstSeries && firstSeries->dataProxy()) { + if (m_axisX) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisX->min()); int count = int(m_axisX->max()) - min + 1; - QStringList subList = static_cast<QBarDataProxy *>(firstSeries->dataProxy()) - ->columnLabels().mid(min, count); - static_cast<Q3DCategoryAxis *>(m_axisX)->dptr()->setDataLabels(subList); + QStringList subList; + if (m_primarySeries && m_primarySeries->dataProxy()) { + subList = static_cast<QBarDataProxy *>(m_primarySeries->dataProxy()) + ->columnLabels().mid(min, count); + } + static_cast<QCategory3DAxis *>(m_axisX)->dptr()->setDataLabels(subList); } } -void Bars3DController::handleBarClicked(const QPoint &position, QBar3DSeries *series) -{ - setSelectedBar(position, series); - - // TODO: pass clicked to parent. (QTRD-2517) - // TODO: Also hover needed? (QTRD-2131) -} - void Bars3DController::handleAxisAutoAdjustRangeChangedInOrientation( - Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) { Q_UNUSED(orientation) Q_UNUSED(autoAdjust) @@ -203,63 +238,120 @@ void Bars3DController::handleSeriesVisibilityChangedBySender(QObject *sender) { Abstract3DController::handleSeriesVisibilityChangedBySender(sender); + adjustAxisRanges(); + // Visibility changes may require disabling/enabling slicing, // so just reset selection to ensure everything is still valid. setSelectedBar(m_selectedBar, m_selectedBarSeries); } +void Bars3DController::handlePendingClick() +{ + // This function is called while doing the sync, so it is okay to query from renderer + QPoint position = m_renderer->clickedPosition(); + QBar3DSeries *series = static_cast<QBar3DSeries *>(m_renderer->clickedSeries()); + + setSelectedBar(position, series); + + m_renderer->resetClickedStatus(); +} + QPoint Bars3DController::invalidSelectionPosition() { static QPoint invalidSelectionPos(-1, -1); return invalidSelectionPos; } -void Bars3DController::setAxisX(Q3DAbstractAxis *axis) +void Bars3DController::setAxisX(QAbstract3DAxis *axis) { Abstract3DController::setAxisX(axis); handleDataColumnLabelsChanged(); } -void Bars3DController::setAxisZ(Q3DAbstractAxis *axis) +void Bars3DController::setAxisZ(QAbstract3DAxis *axis) { Abstract3DController::setAxisZ(axis); handleDataRowLabelsChanged(); } -void Bars3DController::addSeries(QAbstract3DSeries *series) +void Bars3DController::setPrimarySeries(QBar3DSeries *series) { - Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeBar); - - bool firstAdded = !m_seriesList.size(); - - Abstract3DController::addSeries(series); - - if (firstAdded) { - adjustAxisRanges(); + if (!series) { + if (m_seriesList.size()) + series = static_cast<QBar3DSeries *>(m_seriesList.at(0)); + } else if (!m_seriesList.contains(series)) { + // Add nonexistent series. + addSeries(series); + } + if (m_primarySeries != series) { + m_primarySeries = series; handleDataRowLabelsChanged(); handleDataColumnLabelsChanged(); + emit primarySeriesChanged(m_primarySeries); } +} + +QBar3DSeries *Bars3DController::primarySeries() const +{ + return m_primarySeries; +} - QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series); - if (barSeries->selectedBar() != invalidSelectionPosition()) - setSelectedBar(barSeries->selectedBar(), barSeries); +void Bars3DController::addSeries(QAbstract3DSeries *series) +{ + insertSeries(m_seriesList.size(), series); } void Bars3DController::removeSeries(QAbstract3DSeries *series) { - bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series); + bool wasVisible = (series && series->d_ptr->m_controller == this && series->isVisible()); Abstract3DController::removeSeries(series); if (m_selectedBarSeries == series) setSelectedBar(invalidSelectionPosition(), 0); - if (firstRemoved) { + if (wasVisible) adjustAxisRanges(); + // If primary series is removed, reset it to default + if (series == m_primarySeries) { + if (m_seriesList.size()) + m_primarySeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); + else + m_primarySeries = 0; + handleDataRowLabelsChanged(); handleDataColumnLabelsChanged(); + + emit primarySeriesChanged(m_primarySeries); + } +} + +void Bars3DController::insertSeries(int index, QAbstract3DSeries *series) +{ + Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeBar); + + int oldSize = m_seriesList.size(); + + Abstract3DController::insertSeries(index, series); + + if (oldSize != m_seriesList.size()) { + if (series->isVisible()) + adjustAxisRanges(); + + QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series); + if (!oldSize) { + m_primarySeries = barSeries; + handleDataRowLabelsChanged(); + handleDataColumnLabelsChanged(); + } + + if (barSeries->selectedBar() != invalidSelectionPosition()) + setSelectedBar(barSeries->selectedBar(), barSeries); + + if (!oldSize) + emit primarySeriesChanged(m_primarySeries); } } @@ -292,6 +384,19 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender) setSelectedBar(m_selectedBar, m_selectedBarSeries); } +void Bars3DController::setMultiSeriesScaling(bool uniform) +{ + m_isMultiSeriesUniform = uniform; + + m_changeTracker.multiSeriesScalingChanged = true; + emitNeedRender(); +} + +bool Bars3DController::multiSeriesScaling() const +{ + return m_isMultiSeriesUniform; +} + void Bars3DController::setBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative) { m_barThicknessRatio = thicknessRatio; @@ -317,13 +422,14 @@ bool Bars3DController::isBarSpecRelative() return m_isBarSpecRelative; } -void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode) +void Bars3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { - if (mode.testFlag(QDataVis::SelectionSlice) - && (mode.testFlag(QDataVis::SelectionRow) == mode.testFlag(QDataVis::SelectionColumn))) { + if (mode.testFlag(QAbstract3DGraph::SelectionSlice) + && (mode.testFlag(QAbstract3DGraph::SelectionRow) + == mode.testFlag(QAbstract3DGraph::SelectionColumn))) { qWarning("Must specify one of either row or column selection mode in conjunction with slicing mode."); } else { - QDataVis::SelectionFlags oldMode = selectionMode(); + QAbstract3DGraph::SelectionFlags oldMode = selectionMode(); Abstract3DController::setSelectionMode(mode); @@ -334,8 +440,8 @@ void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode) // Special case: Always deactivate slicing when changing away from slice // automanagement, as this can't be handled in setSelectedBar. - if (!mode.testFlag(QDataVis::SelectionSlice) - && oldMode.testFlag(QDataVis::SelectionSlice)) { + if (!mode.testFlag(QAbstract3DGraph::SelectionSlice) + && oldMode.testFlag(QAbstract3DGraph::SelectionSlice)) { scene()->setSlicingActive(false); } } @@ -353,7 +459,7 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri adjustSelectionPosition(pos, series); - if (selectionMode().testFlag(QDataVis::SelectionSlice)) { + if (selectionMode().testFlag(QAbstract3DGraph::SelectionSlice)) { // If the selected bar is outside data window, or there is no visible selected bar, disable slicing if (pos.x() < m_axisZ->min() || pos.x() > m_axisZ->max() || pos.y() < m_axisX->min() || pos.y() > m_axisX->max() @@ -383,11 +489,16 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri } } +void Bars3DController::clearSelection() +{ + setSelectedBar(invalidSelectionPosition(), 0); +} + void Bars3DController::adjustAxisRanges() { - Q3DCategoryAxis *categoryAxisZ = static_cast<Q3DCategoryAxis *>(m_axisZ); - Q3DCategoryAxis *categoryAxisX = static_cast<Q3DCategoryAxis *>(m_axisX); - Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisY); + QCategory3DAxis *categoryAxisZ = static_cast<QCategory3DAxis *>(m_axisZ); + QCategory3DAxis *categoryAxisX = static_cast<QCategory3DAxis *>(m_axisX); + QValue3DAxis *valueAxis = static_cast<QValue3DAxis *>(m_axisY); bool adjustZ = (categoryAxisZ && categoryAxisZ->isAutoAdjustRange()); bool adjustX = (categoryAxisX && categoryAxisX->isAutoAdjustRange()); @@ -493,11 +604,11 @@ void Bars3DController::adjustSelectionPosition(QPoint &pos, const QBar3DSeries * } } -Q3DAbstractAxis *Bars3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation) +QAbstract3DAxis *Bars3DController::createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation) { - Q3DAbstractAxis *defaultAxis = 0; + QAbstract3DAxis *defaultAxis = 0; - if (orientation == Q3DAbstractAxis::AxisOrientationY) + if (orientation == QAbstract3DAxis::AxisOrientationY) defaultAxis = createDefaultValueAxis(); else defaultAxis = createDefaultCategoryAxis(); @@ -505,4 +616,4 @@ Q3DAbstractAxis *Bars3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrient return defaultAxis; } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION |