From 25f13122a237cebe72e1eb1f821081d21240b22b Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Fri, 2 Aug 2019 13:13:23 +0200 Subject: [PATCH] #4517 Implement highlighting function for plot curves --- .../Application/Tools/RiaColorTools.cpp | 13 +++ .../Application/Tools/RiaColorTools.h | 2 + .../UserInterface/RiuGridCrossQwtPlot.cpp | 2 - ApplicationCode/UserInterface/RiuQwtPlot.cpp | 107 +++++++++++++++++- ApplicationCode/UserInterface/RiuQwtPlot.h | 12 ++ 5 files changed, 131 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/Application/Tools/RiaColorTools.cpp b/ApplicationCode/Application/Tools/RiaColorTools.cpp index fbbec44c89..a15f4ed9b4 100644 --- a/ApplicationCode/Application/Tools/RiaColorTools.cpp +++ b/ApplicationCode/Application/Tools/RiaColorTools.cpp @@ -19,6 +19,7 @@ #include "RiaColorTools.h" +#include "cvfAssert.h" #include "cvfMath.h" #include @@ -141,6 +142,18 @@ cvf::Color3f RiaColorTools::fromQColorTo3f(QColor color) return cvf::Color3f(color.redF(), color.greenF(), color.blueF()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QColor RiaColorTools::blendQColors(const QColor& color1, const QColor& color2, int weight1 /*= 1*/, int weight2 /*= 1*/) +{ + CVF_ASSERT(weight1 > 0 && weight2 > 0); + int weightsum = weight1 + weight2; + return QColor((color1.red() * weight1 + color2.red() * weight2) / weightsum, + (color1.green() * weight1 + color2.green() * weight2) / weightsum, + (color1.blue() * weight1 + color2.blue() * weight2) / weightsum); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/Tools/RiaColorTools.h b/ApplicationCode/Application/Tools/RiaColorTools.h index e99221325b..55fc12ac28 100644 --- a/ApplicationCode/Application/Tools/RiaColorTools.h +++ b/ApplicationCode/Application/Tools/RiaColorTools.h @@ -43,6 +43,8 @@ public: static QColor toQColor(cvf::Color4f color); static cvf::Color3f fromQColorTo3f(QColor); + static QColor blendQColors(const QColor& color1, const QColor& color2, int weight1 = 1, int weight2 = 1); + private: static float relativeLuminance(cvf::Color3f backgroundColor); static float calculateNonLinearColorValue(float colorFraction); diff --git a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp index 8580aaddb5..b2e74aaff4 100644 --- a/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuGridCrossQwtPlot.cpp @@ -398,7 +398,6 @@ void RiuGridCrossQwtPlot::selectSample(QwtPlotCurve* curve, int sampleNumber) curveLabel.setBorderRadius(2.0); m_selectedPointMarker->setLabel(curveLabel); } - replot(); } //-------------------------------------------------------------------------------------------------- @@ -407,7 +406,6 @@ void RiuGridCrossQwtPlot::selectSample(QwtPlotCurve* curve, int sampleNumber) void RiuGridCrossQwtPlot::clearSampleSelection() { m_selectedPointMarker->detach(); - replot(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuQwtPlot.cpp b/ApplicationCode/UserInterface/RiuQwtPlot.cpp index ccbb7dde03..d4b06b8dfa 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuQwtPlot.cpp @@ -18,6 +18,8 @@ #include "RiuQwtPlot.h" +#include "RiaColorTools.h" + #include "RimProject.h" #include "RiuPlotMainWindowTools.h" @@ -82,6 +84,7 @@ RiuQwtPlot::RiuQwtPlot(RimViewWindow* viewWindow, QWidget* parent) : QwtPlot(par RiuQwtPlotTools::setCommonPlotBehaviour(this); RiuQwtPlotTools::setDefaultAxes(this); + } //-------------------------------------------------------------------------------------------------- @@ -124,7 +127,7 @@ QSize RiuQwtPlot::minimumSizeHint() const /// Empty default implementation //-------------------------------------------------------------------------------------------------- void RiuQwtPlot::selectSample(QwtPlotCurve* curve, int sampleNumber) -{ +{ } //-------------------------------------------------------------------------------------------------- @@ -134,6 +137,15 @@ void RiuQwtPlot::clearSampleSelection() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlot::hideEvent(QHideEvent* event) +{ + resetCurveHighlighting(); + QwtPlot::hideEvent(event); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -195,6 +207,7 @@ void RiuQwtPlot::selectClosestCurve(const QPoint& pos) } } + resetCurveHighlighting(); if (closestCurve && distMin < 20) { CVF_ASSERT(closestCurvePoint >= 0); @@ -209,18 +222,106 @@ void RiuQwtPlot::selectClosestCurve(const QPoint& pos) { RiuPlotMainWindowTools::showPlotMainWindow(); RiuPlotMainWindowTools::selectAsCurrentItem(selectedPlotObject); + highlightCurve(closestCurve); } } } - + if (closestCurve && distMin < 10) { - selectSample(closestCurve, closestCurvePoint); + selectSample(closestCurve, closestCurvePoint); } else { clearSampleSelection(); } + + replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlot::highlightCurve(const QwtPlotCurve* closestCurve) +{ + for (QwtPlotItem* plotItem : this->itemList()) + { + QwtPlotCurve* plotCurve = dynamic_cast(plotItem); + if (plotCurve) + { + QPen existingPen = plotCurve->pen(); + QColor bgColor = this->canvasBackground().color(); + + QColor curveColor = existingPen.color(); + QColor symbolColor; + QColor symbolLineColor; + + QwtSymbol* symbol = const_cast(plotCurve->symbol()); + if (symbol) + { + symbolColor = symbol->brush().color(); + symbolLineColor = symbol->pen().color(); + } + + if (plotCurve == closestCurve) + { + cvf::Color3f cvfBgColor = RiaColorTools::fromQColorTo3f(bgColor); + cvf::Color3f cvfFgColor = RiaColorTools::contrastColor(cvfBgColor); + QColor fgColor = RiaColorTools::toQColor(cvfFgColor); + + QColor blendedColor = RiaColorTools::blendQColors(fgColor, curveColor, 1, 2); + QColor blendedSymbolColor = RiaColorTools::blendQColors(fgColor, symbolColor, 1, 2); + QColor blendedSymbolLineColor = RiaColorTools::blendQColors(fgColor, symbolLineColor, 1, 2); + + plotCurve->setPen(blendedColor, existingPen.width(), existingPen.style()); + if (symbol) + { + symbol->setColor(blendedSymbolColor); + symbol->setPen(blendedSymbolLineColor, symbol->pen().width(), symbol->pen().style()); + } + } + else + { + QColor blendedColor = RiaColorTools::blendQColors(bgColor, curveColor, 3, 1); + QColor blendedSymbolColor = RiaColorTools::blendQColors(bgColor, symbolColor, 3, 1); + QColor blendedSymbolLineColor = RiaColorTools::blendQColors(bgColor, symbolLineColor, 3, 1); + + plotCurve->setPen(blendedColor, existingPen.width(), existingPen.style()); + if (symbol) + { + symbol->setColor(blendedSymbolColor); + symbol->setPen(blendedSymbolLineColor, symbol->pen().width(), symbol->pen().style()); + } + } + CurveColors curveColors = {curveColor, symbolColor, symbolLineColor}; + m_originalCurveColors.insert(std::make_pair(plotCurve, curveColors)); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlot::resetCurveHighlighting() +{ + for (QwtPlotItem* plotItem : this->itemList()) + { + QwtPlotCurve* plotCurve = dynamic_cast(plotItem); + if (plotCurve && m_originalCurveColors.count(plotCurve)) + { + const QPen& existingPen = plotCurve->pen(); + auto colors = m_originalCurveColors[plotCurve]; + plotCurve->setPen(colors.lineColor, existingPen.width(), existingPen.style()); + + QwtSymbol* symbol = const_cast(plotCurve->symbol()); + if (symbol) + { + symbol->setColor(colors.symbolColor); + symbol->setPen(colors.symbolLineColor, symbol->pen().width(), symbol->pen().style()); + } + } + } + m_originalCurveColors.clear(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuQwtPlot.h b/ApplicationCode/UserInterface/RiuQwtPlot.h index ff81a5d539..e61541e605 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuQwtPlot.h @@ -61,18 +61,30 @@ protected: virtual void selectSample(QwtPlotCurve* curve, int sampleNumber); virtual void clearSampleSelection(); + + virtual void hideEvent(QHideEvent *event) override; + private: void selectClosestCurve(const QPoint& pos); + void highlightCurve(const QwtPlotCurve* closestCurve); + void resetCurveHighlighting(); private slots: void onZoomedSlot( ); void onAxisClicked(int axis, double value); private: + struct CurveColors + { + QColor lineColor; + QColor symbolColor; + QColor symbolLineColor; + }; caf::PdmPointer m_ownerViewWindow; QPointer m_zoomerLeft; QPointer m_zoomerRight; + std::map m_originalCurveColors; };