From 277b96690357eba50e288316e74524a72a323427 Mon Sep 17 00:00:00 2001 From: Soumyadeep Basu <44787782+basusoumyadeep@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:23:11 +0200 Subject: [PATCH 1/3] limit the HeadsUpDisplayUpdate by timer[skip ci] --- src/ScatterplotPlugin.cpp | 46 ++++++++++++++++++++++++++------------- src/ScatterplotPlugin.h | 5 ++++- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/ScatterplotPlugin.cpp b/src/ScatterplotPlugin.cpp index a2dd6aa..efc13df 100644 --- a/src/ScatterplotPlugin.cpp +++ b/src/ScatterplotPlugin.cpp @@ -368,14 +368,18 @@ void ScatterplotPlugin::init() }); #endif - updateHeadsUpDisplay(); - - connect(&_positionDataset, &Dataset<>::changed, this, &ScatterplotPlugin::updateHeadsUpDisplay); - connect(&_positionDataset, &Dataset<>::guiNameChanged, this, &ScatterplotPlugin::updateHeadsUpDisplay); - connect(&_settingsAction.getColoringAction(), &ColoringAction::currentColorDatasetChanged, this, &ScatterplotPlugin::updateHeadsUpDisplay); - connect(&_settingsAction.getColoringAction().getColorByAction(), &OptionAction::currentIndexChanged, this, &ScatterplotPlugin::updateHeadsUpDisplay); - connect(&_settingsAction.getPlotAction().getPointPlotAction().getSizeAction(), &ScalarAction::sourceDataChanged, this, &ScatterplotPlugin::updateHeadsUpDisplay); - connect(&_settingsAction.getPlotAction().getPointPlotAction().getOpacityAction(), &ScalarAction::sourceDataChanged, this, &ScatterplotPlugin::updateHeadsUpDisplay); + _hudUpdateTimer = new QTimer(this); + _hudUpdateTimer->setSingleShot(true); + connect(_hudUpdateTimer, &QTimer::timeout, this, &ScatterplotPlugin::updateHeadsUpDisplay); + + connect(&_positionDataset, &Dataset<>::changed, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + connect(&_positionDataset, &Dataset<>::guiNameChanged, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + connect(&_settingsAction.getColoringAction(), &ColoringAction::currentColorDatasetChanged, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + connect(&_settingsAction.getColoringAction().getColorByAction(), &OptionAction::currentIndexChanged, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + connect(&_settingsAction.getPlotAction().getPointPlotAction().getSizeAction(), &ScalarAction::sourceDataChanged, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + connect(&_settingsAction.getPlotAction().getPointPlotAction().getOpacityAction(), &ScalarAction::sourceDataChanged, this, &ScatterplotPlugin::scheduleHeadsUpDisplayUpdate); + + scheduleHeadsUpDisplayUpdate(); } void ScatterplotPlugin::loadData(const Datasets& datasets) @@ -970,26 +974,38 @@ void ScatterplotPlugin::updateSelection() } } +void ScatterplotPlugin::scheduleHeadsUpDisplayUpdate() +{ + if (_hudUpdateTimer) + _hudUpdateTimer->start(20); +} + void ScatterplotPlugin::updateHeadsUpDisplay() { getHeadsUpDisplayAction().removeAllHeadsUpDisplayItems(); if (_positionDataset.isValid()) { - const auto datasetsItem = getHeadsUpDisplayAction().addHeadsUpDisplayItem("Datasets", "", ""); + const auto datasetsItem = getHeadsUpDisplayAction().addHeadsUpDisplayItem("Datasets", "", nullptr); + // Defensive: Check both pointer and index validity + if (!datasetsItem || !datasetsItem->getIndex().isValid()) + return; + + // Only add child items if parent is valid and part of the model getHeadsUpDisplayAction().addHeadsUpDisplayItem("Position by:", _positionDataset->getGuiName(), "", datasetsItem); auto addMetaDataToHeadsUpDisplay = [this](const QString& metaDataName, const Dataset<> data, const util::HeadsUpDisplayItemSharedPtr& itemPtr) { - if (data.isValid()) + if (data.isValid() && itemPtr && itemPtr->getIndex().isValid()) getHeadsUpDisplayAction().addHeadsUpDisplayItem(QString("%1 by:").arg(metaDataName), data->getGuiName(), "", itemPtr); }; - addMetaDataToHeadsUpDisplay("Color", _settingsAction.getColoringAction().getCurrentColorDataset(), datasetsItem); - addMetaDataToHeadsUpDisplay("Size", _settingsAction.getPlotAction().getPointPlotAction().getSizeAction().getCurrentDataset(), datasetsItem); + addMetaDataToHeadsUpDisplay("Color", _settingsAction.getColoringAction().getCurrentColorDataset(), datasetsItem); + addMetaDataToHeadsUpDisplay("Size", _settingsAction.getPlotAction().getPointPlotAction().getSizeAction().getCurrentDataset(), datasetsItem); addMetaDataToHeadsUpDisplay("Opacity", _settingsAction.getPlotAction().getPointPlotAction().getOpacityAction().getCurrentDataset(), datasetsItem); - } else { - getHeadsUpDisplayAction().addHeadsUpDisplayItem("No datasets loaded", "", ""); + } + else { + getHeadsUpDisplayAction().addHeadsUpDisplayItem("No datasets loaded", "", nullptr); } } @@ -1006,7 +1022,7 @@ void ScatterplotPlugin::fromVariantMap(const QVariantMap& variantMap) _primaryToolbarAction.fromParentVariantMap(variantMap); _settingsAction.fromParentVariantMap(variantMap); - updateHeadsUpDisplay(); + scheduleHeadsUpDisplayUpdate(); if (pointRenderer.getNavigator().getNavigationAction().getSerializationCountFrom() == 0) { qDebug() << "Resetting view"; diff --git a/src/ScatterplotPlugin.h b/src/ScatterplotPlugin.h index 4ef3c3f..a186671 100644 --- a/src/ScatterplotPlugin.h +++ b/src/ScatterplotPlugin.h @@ -83,6 +83,9 @@ class ScatterplotPlugin : public ViewPlugin /** Use the sampler pixel selection tool to sample data points */ void samplePoints(); + /** Schedule an update of the heads-up display (HUD) **/ + void scheduleHeadsUpDisplayUpdate(); + public: /** Get reference to the scatter plot widget */ @@ -120,7 +123,7 @@ class ScatterplotPlugin : public ViewPlugin SettingsAction _settingsAction; /** Group action for all settings */ HorizontalToolbarAction _primaryToolbarAction; /** Horizontal toolbar for primary content */ QRectF _selectionBoundaries; /** Boundaries of the selection */ - + QTimer* _hudUpdateTimer = nullptr; static const std::int32_t LAZY_UPDATE_INTERVAL = 2; }; From 3eb3a4474e6904eac57c5db6857cc19bae36be1a Mon Sep 17 00:00:00 2001 From: Soumyadeep Basu <44787782+basusoumyadeep@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:55:16 +0200 Subject: [PATCH 2/3] add destructor --- src/ScalarSourceAction.cpp | 8 ++++++++ src/ScalarSourceAction.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/ScalarSourceAction.cpp b/src/ScalarSourceAction.cpp index 19ed806..392e586 100644 --- a/src/ScalarSourceAction.cpp +++ b/src/ScalarSourceAction.cpp @@ -31,6 +31,9 @@ ScalarSourceAction::ScalarSourceAction(QObject* parent, const QString& title) : _offsetAction.setSuffix("px"); const auto scalarSourceChanged = [this]() -> void { + + if (_destroyed) return; + const auto sourceIndex = _pickerAction.getCurrentIndex(); _dimensionPickerAction.setEnabled(sourceIndex >= ScalarSourceModel::DefaultRow::DatasetStart); @@ -61,6 +64,11 @@ ScalarSourceAction::ScalarSourceAction(QObject* parent, const QString& title) : scalarSourceChanged(); } +ScalarSourceAction::~ScalarSourceAction() +{ + _destroyed = true; +} + ScalarSourceModel& ScalarSourceAction::getModel() { return _model; diff --git a/src/ScalarSourceAction.h b/src/ScalarSourceAction.h index 5387c31..6d00922 100644 --- a/src/ScalarSourceAction.h +++ b/src/ScalarSourceAction.h @@ -29,6 +29,9 @@ class ScalarSourceAction : public GroupAction */ Q_INVOKABLE ScalarSourceAction(QObject* parent, const QString& title); + /** Destructor */ + ~ScalarSourceAction() override; + /** Get the scalar source model */ ScalarSourceModel& getModel(); @@ -88,6 +91,7 @@ class ScalarSourceAction : public GroupAction DimensionPickerAction _dimensionPickerAction; /** Dimension picker action */ DecimalAction _offsetAction; /** Scalar source offset action */ DecimalRangeAction _rangeAction; /** Range action */ + bool _destroyed = false; friend class mv::AbstractActionsManager; }; From 038f0fa2e00d8a2ff426f4bd39d72cbf9d36dba8 Mon Sep 17 00:00:00 2001 From: sbvis Date: Fri, 19 Sep 2025 23:44:39 +0200 Subject: [PATCH 3/3] Revert "add destructor" This reverts commit 3eb3a4474e6904eac57c5db6857cc19bae36be1a. --- src/ScalarSourceAction.cpp | 8 -------- src/ScalarSourceAction.h | 4 ---- 2 files changed, 12 deletions(-) diff --git a/src/ScalarSourceAction.cpp b/src/ScalarSourceAction.cpp index 392e586..19ed806 100644 --- a/src/ScalarSourceAction.cpp +++ b/src/ScalarSourceAction.cpp @@ -31,9 +31,6 @@ ScalarSourceAction::ScalarSourceAction(QObject* parent, const QString& title) : _offsetAction.setSuffix("px"); const auto scalarSourceChanged = [this]() -> void { - - if (_destroyed) return; - const auto sourceIndex = _pickerAction.getCurrentIndex(); _dimensionPickerAction.setEnabled(sourceIndex >= ScalarSourceModel::DefaultRow::DatasetStart); @@ -64,11 +61,6 @@ ScalarSourceAction::ScalarSourceAction(QObject* parent, const QString& title) : scalarSourceChanged(); } -ScalarSourceAction::~ScalarSourceAction() -{ - _destroyed = true; -} - ScalarSourceModel& ScalarSourceAction::getModel() { return _model; diff --git a/src/ScalarSourceAction.h b/src/ScalarSourceAction.h index 6d00922..5387c31 100644 --- a/src/ScalarSourceAction.h +++ b/src/ScalarSourceAction.h @@ -29,9 +29,6 @@ class ScalarSourceAction : public GroupAction */ Q_INVOKABLE ScalarSourceAction(QObject* parent, const QString& title); - /** Destructor */ - ~ScalarSourceAction() override; - /** Get the scalar source model */ ScalarSourceModel& getModel(); @@ -91,7 +88,6 @@ class ScalarSourceAction : public GroupAction DimensionPickerAction _dimensionPickerAction; /** Dimension picker action */ DecimalAction _offsetAction; /** Scalar source offset action */ DecimalRangeAction _rangeAction; /** Range action */ - bool _destroyed = false; friend class mv::AbstractActionsManager; };