#4158 Implement info box for grid cross plots and improve plot overlay legends

This commit is contained in:
Gaute Lindkvist 2019-03-25 14:47:55 +01:00
parent c47f2a30d8
commit aa32caae33
16 changed files with 351 additions and 38 deletions

View File

@ -48,6 +48,7 @@ RimGridCrossPlot::RimGridCrossPlot()
{ {
CAF_PDM_InitObject("Grid Cross Plot", ":/SummaryXPlotLight16x16.png", "", ""); CAF_PDM_InitObject("Grid Cross Plot", ":/SummaryXPlotLight16x16.png", "", "");
CAF_PDM_InitField(&m_showInfoBox, "ShowInfoBox", true, "Show Info Box", "", "", "");
CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Show Legend", "", "", ""); CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Show Legend", "", "", "");
CAF_PDM_InitField(&m_legendFontSize, "LegendFontSize", 10, "Legend Font Size", "", "", ""); CAF_PDM_InitField(&m_legendFontSize, "LegendFontSize", 10, "Legend Font Size", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "Name Config", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "Name Config", "", "", "");
@ -94,13 +95,18 @@ RimGridCrossPlotCurveSet* RimGridCrossPlot::createCurveSet()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
int RimGridCrossPlot::indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSet) const int RimGridCrossPlot::indexOfCurveSet(const RimGridCrossPlotCurveSet* curveSetToCheck) const
{ {
for (size_t i = 0; i < m_crossPlotCurveSets.size(); ++i) int index = 0;
for (auto curveSet : m_crossPlotCurveSets())
{ {
if (curveSet == m_crossPlotCurveSets[i]) if (curveSet == curveSetToCheck)
{ {
return static_cast<int>(i); return index;
}
if (curveSet->isChecked() && curveSet->visibleCurveCount() > 0u)
{
index++;
} }
} }
return -1; return -1;
@ -247,6 +253,14 @@ QString RimGridCrossPlot::createAutoName() const
return autoName.join(" "); return autoName.join(" ");
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridCrossPlot::showInfoBox() const
{
return m_showInfoBox();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -399,6 +413,7 @@ void RimGridCrossPlot::onLoadDataAndUpdate()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimGridCrossPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) void RimGridCrossPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{ {
uiOrdering.add(&m_showInfoBox);
uiOrdering.add(&m_showLegend); uiOrdering.add(&m_showLegend);
if (m_showLegend()) if (m_showLegend())

View File

@ -66,6 +66,7 @@ public:
void reattachCurvesToQwtAndReplot(); void reattachCurvesToQwtAndReplot();
QString createAutoName() const override; QString createAutoName() const override;
bool showInfoBox() const;
caf::PdmFieldHandle* userDescriptionField() override; caf::PdmFieldHandle* userDescriptionField() override;
void detachAllCurves(); void detachAllCurves();
void performAutoNameUpdate() override; void performAutoNameUpdate() override;
@ -112,6 +113,7 @@ protected:
RimGridCrossPlotNameConfig* nameConfig(); RimGridCrossPlotNameConfig* nameConfig();
private: private:
caf::PdmField<bool> m_showInfoBox;
caf::PdmField<bool> m_showLegend; caf::PdmField<bool> m_showLegend;
caf::PdmField<int> m_legendFontSize; caf::PdmField<int> m_legendFontSize;
caf::PdmChildField<RimGridCrossPlotNameConfig*> m_nameConfig; caf::PdmChildField<RimGridCrossPlotNameConfig*> m_nameConfig;

View File

@ -92,6 +92,14 @@ int RimGridCrossPlotCurve::groupIndex() const
return m_groupIndex; return m_groupIndex;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGridCrossPlotCurve::sampleCount() const
{
return m_qwtPlotCurve->dataSize();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -43,9 +43,9 @@ public:
void setGroupingInformation(int curveSetIndex, int groupIndex); void setGroupingInformation(int curveSetIndex, int groupIndex);
void setSamples(const std::vector<double>& xValues, const std::vector<double>& yValues); void setSamples(const std::vector<double>& xValues, const std::vector<double>& yValues);
void setCurveAutoAppearance(); void setCurveAutoAppearance();
int groupIndex() const; int groupIndex() const;
size_t sampleCount() const;
protected: protected:
void determineSymbol(); void determineSymbol();

View File

@ -198,6 +198,36 @@ QString RimGridCrossPlotCurveSet::yAxisName() const
return m_yAxisProperty->resultVariableUiShortName(); return m_yAxisProperty->resultVariableUiShortName();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCrossPlotCurveSet::infoText() const
{
if (!m_case()) return "";
if (visibleCurveCount() == 0u) return "";
QStringList textLines;
textLines += QString("<b>Case:</b> %1").arg(m_case()->caseUserDescription());
textLines += QString("<b>Parameters:</b>: %1 x %2")
.arg(m_xAxisProperty->resultVariableUiShortName())
.arg(m_yAxisProperty->resultVariableUiShortName());
if (m_timeStep != -1)
{
textLines += QString("<b>Time step:</b> %1").arg(timeStepString());
}
if (m_grouping != NO_GROUPING)
{
textLines += QString("<b>Grouped By:</b> %1").arg(groupParameter());
}
if (m_cellFilterView())
{
textLines += QString("<b>Filter view:</b> %1").arg(m_cellFilterView->name());
}
textLines += QString("<b>Sample Count:</b> %1").arg(sampleCount());
return textLines.join("<br/>\n");
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -606,6 +636,32 @@ void RimGridCrossPlotCurveSet::destroyCurves()
m_crossPlotCurves.deleteAllChildObjects(); m_crossPlotCurves.deleteAllChildObjects();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGridCrossPlotCurveSet::visibleCurveCount() const
{
size_t visibleCurves = 0;
for (auto curve : m_crossPlotCurves)
{
if (curve->isCurveVisible()) visibleCurves++;
}
return visibleCurves;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimGridCrossPlotCurveSet::sampleCount() const
{
size_t sampleCount = 0;
for (auto curve : m_crossPlotCurves)
{
if (curve->isCurveVisible()) sampleCount += curve->sampleCount();
}
return sampleCount;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -97,6 +97,7 @@ public:
void setParentQwtPlotNoReplot(QwtPlot* parent); void setParentQwtPlotNoReplot(QwtPlot* parent);
QString xAxisName() const; QString xAxisName() const;
QString yAxisName() const; QString yAxisName() const;
QString infoText() const;
int indexInPlot() const; int indexInPlot() const;
QString createAutoName() const override; QString createAutoName() const override;
@ -131,6 +132,8 @@ public:
void setCustomColor(const cvf::Color3f color); void setCustomColor(const cvf::Color3f color);
void destroyCurves(); void destroyCurves();
size_t visibleCurveCount() const;
size_t sampleCount() const;
protected: protected:
void initAfterRead() override; void initAfterRead() override;
void onLoadDataAndUpdate(bool updateParentPlot); void onLoadDataAndUpdate(bool updateParentPlot);
@ -175,5 +178,5 @@ private:
caf::PdmField<bool> m_useCustomColor; caf::PdmField<bool> m_useCustomColor;
caf::PdmField<cvf::Color3f> m_customColor; caf::PdmField<cvf::Color3f> m_customColor;
caf::PdmChildField<RimPlotCellFilterCollection*> m_plotCellFilterCollection;; caf::PdmChildField<RimPlotCellFilterCollection*> m_plotCellFilterCollection;;
}; };

View File

@ -80,6 +80,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.h ${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.h
${CMAKE_CURRENT_LIST_DIR}/RiuMeasurementViewEventFilter.h ${CMAKE_CURRENT_LIST_DIR}/RiuMeasurementViewEventFilter.h
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
) )
set (SOURCE_GROUP_SOURCE_FILES set (SOURCE_GROUP_SOURCE_FILES
@ -159,6 +160,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuDockWidgetTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.cpp
) )
list(APPEND CODE_HEADER_FILES list(APPEND CODE_HEADER_FILES
@ -205,6 +207,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuMessagePanel.h
${CMAKE_CURRENT_LIST_DIR}/RiuExpressionContextMenuManager.h ${CMAKE_CURRENT_LIST_DIR}/RiuExpressionContextMenuManager.h
${CMAKE_CURRENT_LIST_DIR}/RiuCalculationsContextMenuManager.h ${CMAKE_CURRENT_LIST_DIR}/RiuCalculationsContextMenuManager.h
${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.h ${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
) )
list(APPEND QT_UI_FILES list(APPEND QT_UI_FILES

View File

@ -41,16 +41,11 @@
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget(QWidget* parent/*=0*/) RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget(QWidget* parent/*=0*/, QWidget* widgetToSnapTo)
: QWidget(parent) : RiuDraggableOverlayFrame(parent, widgetToSnapTo)
{ {
auto hblayout = new QHBoxLayout(this); this->layout()->setMargin(0);
hblayout->setMargin(0); this->layout()->setSpacing(0);
hblayout->setSpacing(0);
this->setLayout(hblayout);
m_overlayItemLabel = new QLabel(this);
this->layout()->addWidget(m_overlayItemLabel);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -126,7 +121,7 @@ void RiuCvfOverlayItemWidget::updateFromOverlayItem( cvf::OverlayItem * item)
QPixmap pixmap = QPixmap::fromImage(image); QPixmap pixmap = QPixmap::fromImage(image);
delete viewer; delete viewer;
m_overlayItemLabel->setPixmap(pixmap); m_overlayItemLabel->setPixmap(pixmap);
this->setMinimumSize(QSize(width, height)); this->setMinimumSize(QSize(width, height));
this->resize(QSize(width, height)); this->resize(QSize(width, height));

View File

@ -18,6 +18,8 @@
#pragma once #pragma once
#include "RiuDraggableOverlayFrame.h"
#include <QWidget> #include <QWidget>
class QLabel; class QLabel;
@ -31,18 +33,15 @@ namespace cvf
// //
// //
//================================================================================================== //==================================================================================================
class RiuCvfOverlayItemWidget : public QWidget class RiuCvfOverlayItemWidget : public RiuDraggableOverlayFrame
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr); explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr, QWidget* widgetToSnapTo = nullptr);
~RiuCvfOverlayItemWidget() override; ~RiuCvfOverlayItemWidget() override;
void updateFromOverlayItem( cvf::OverlayItem * item); void updateFromOverlayItem( cvf::OverlayItem * item);
// virtual QSize sizeHint() const override; // virtual QSize sizeHint() const override;
// virtual QSize minimumSizeHint() const override; // virtual QSize minimumSizeHint() const override;
protected:
QLabel* m_overlayItemLabel;
}; };

View File

@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiuDraggableOverlayFrame.h"
#include "RiuWidgetDragger.h"
#include <QGraphicsDropShadowEffect>
#include <QLabel>
#include <QVBoxLayout>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuDraggableOverlayFrame::RiuDraggableOverlayFrame(QWidget* parent, QWidget* widgetToSnapTo, const QColor& backgroundColor)
: QFrame(parent)
{
RiuWidgetDragger* dragger = new RiuWidgetDragger(this, widgetToSnapTo);
QPalette pal = this->palette();
pal.setColor(QPalette::Background, backgroundColor);
setAutoFillBackground(true);
setPalette(pal);
setFrameShape(QFrame::Box);
QGraphicsDropShadowEffect* dropShadowEffect = new QGraphicsDropShadowEffect(this);
dropShadowEffect->setOffset(1.0, 1.0);
dropShadowEffect->setBlurRadius(3.0);
dropShadowEffect->setColor(QColor(100, 100, 100, 100));
setGraphicsEffect(dropShadowEffect);
auto hblayout = new QVBoxLayout(this);
this->setLayout(hblayout);
m_overlayItemLabel = new QLabel(this);
hblayout->addWidget(m_overlayItemLabel);
m_overlayItemLabel->setObjectName("OverlayFrameLabel");
m_overlayItemLabel->setGraphicsEffect(nullptr);
m_overlayItemLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
dragger->addWidget(m_overlayItemLabel);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QLabel* RiuDraggableOverlayFrame::label()
{
return m_overlayItemLabel;
}

View File

@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QFrame>
#include <QPointer>
class QColor;
class QLabel;
class RiuDraggableOverlayFrame : public QFrame
{
Q_OBJECT
public:
RiuDraggableOverlayFrame(QWidget* parent, QWidget* widgetToSnapTo = nullptr, const QColor& backgroundColor = QColor(255, 255, 255, 100));
QLabel* label();
protected:
QPointer<QLabel> m_overlayItemLabel;
};

View File

@ -32,8 +32,10 @@
#include "RimPlotAxisProperties.h" #include "RimPlotAxisProperties.h"
#include "RiuPlotAnnotationTool.h" #include "RiuPlotAnnotationTool.h"
#include <QLabel>
#include <QMenu> #include <QMenu>
#include <QResizeEvent> #include <QResizeEvent>
#include <QVBoxLayout>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
@ -42,6 +44,7 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot(RimViewWindow* ownerViewWindow, QWidget
: RiuQwtPlot(ownerViewWindow, parent) : RiuQwtPlot(ownerViewWindow, parent)
{ {
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>(new RiuPlotAnnotationTool()); m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>(new RiuPlotAnnotationTool());
m_infoBox = new RiuDraggableOverlayFrame(this, canvas());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -54,10 +57,7 @@ void RiuGridCrossQwtPlot::addOrUpdateCurveSetLegend(RimGridCrossPlotCurveSet* cu
auto it = m_legendWidgets.find(curveSet); auto it = m_legendWidgets.find(curveSet);
if (it == m_legendWidgets.end() || it->second == nullptr) if (it == m_legendWidgets.end() || it->second == nullptr)
{ {
overlayWidget = new RiuCvfOverlayItemWidget(this); overlayWidget = new RiuCvfOverlayItemWidget(this, canvas());
new RiuWidgetDragger(overlayWidget);
m_legendWidgets[curveSet] = overlayWidget; m_legendWidgets[curveSet] = overlayWidget;
} }
else else
@ -144,9 +144,66 @@ void RiuGridCrossQwtPlot::updateAnnotationObjects(RimPlotAxisProperties* axisPro
void RiuGridCrossQwtPlot::updateLayout() void RiuGridCrossQwtPlot::updateLayout()
{ {
QwtPlot::updateLayout(); QwtPlot::updateLayout();
updateInfoBoxLayout();
updateLegendLayout(); updateLegendLayout();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuGridCrossQwtPlot::updateInfoBoxLayout()
{
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>(ownerPlotDefinition());
if (!crossPlot) return;
bool showInfo = false;
if (crossPlot->showInfoBox())
{
QStringList curveInfoTexts;
for (auto curveSet : crossPlot->curveSets())
{
QString curveInfoText = curveSet->infoText();
if (curveSet->isChecked() && !curveInfoText.isEmpty())
{
curveInfoTexts += curveInfoText;
}
}
QStringList infoText;
if (curveInfoTexts.size() > 1)
{
infoText += QString("<ol style=\"margin-top: 0px; margin-left: 15px; -qt-list-indent:0;\">");
for (QString curveInfoText : curveInfoTexts)
{
infoText += QString("<li>%1</li>").arg(curveInfoText);
}
infoText += QString("</ol>");
}
else if (curveInfoTexts.size() > 0)
{
infoText += curveInfoTexts.front();
}
if (!infoText.empty())
{
m_infoBox->label()->setText(infoText.join("\n"));
m_infoBox->adjustSize();
QRect infoRect = m_infoBox->frameGeometry();
QRect canvasRect = canvas()->frameGeometry();
infoRect.moveTop(canvasRect.top() + 4);
infoRect.moveRight(canvasRect.right() - 4);
m_infoBox->move(infoRect.topLeft());
showInfo = true;
}
}
if (showInfo)
{
m_infoBox->show();
}
else
{
m_infoBox->hide();
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -29,6 +29,7 @@
class RimGridCrossPlotCurveSet; class RimGridCrossPlotCurveSet;
class RiuCvfOverlayItemWidget; class RiuCvfOverlayItemWidget;
class RiuDraggableOverlayFrame;
class RiuPlotAnnotationTool; class RiuPlotAnnotationTool;
class RimPlotAxisProperties; class RimPlotAxisProperties;
@ -55,12 +56,18 @@ public:
protected: protected:
void updateLayout() override; void updateLayout() override;
void updateInfoBoxLayout();
void updateLegendLayout(); void updateLegendLayout();
void resizeEvent(QResizeEvent* e) override; void resizeEvent(QResizeEvent* e) override;
bool resizeOverlayItemToFitPlot(caf::TitledOverlayFrame* overlayItem); bool resizeOverlayItemToFitPlot(caf::TitledOverlayFrame* overlayItem);
void contextMenuEvent(QContextMenuEvent*) override; void contextMenuEvent(QContextMenuEvent*) override;
private: private:
std::map<caf::PdmPointer<RimGridCrossPlotCurveSet>, QPointer<RiuCvfOverlayItemWidget>> m_legendWidgets; typedef caf::PdmPointer<RimGridCrossPlotCurveSet> CurveSetPtr;
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool; typedef QPointer<RiuCvfOverlayItemWidget> LegendPtr;
typedef QPointer<RiuDraggableOverlayFrame> InfoBoxPtr;
InfoBoxPtr m_infoBox;
std::map<CurveSetPtr, LegendPtr> m_legendWidgets;
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
}; };

View File

@ -123,10 +123,7 @@ void RiuSummaryQwtPlot::addOrUpdateEnsembleCurveSetLegend(RimEnsembleCurveSet* c
auto it = m_ensembleLegendWidgets.find(curveSetToShowLegendFor); auto it = m_ensembleLegendWidgets.find(curveSetToShowLegendFor);
if (it == m_ensembleLegendWidgets.end() || it->second == nullptr) if (it == m_ensembleLegendWidgets.end() || it->second == nullptr)
{ {
overlayWidget = new RiuCvfOverlayItemWidget(this); overlayWidget = new RiuCvfOverlayItemWidget(this, canvas());
new RiuWidgetDragger(overlayWidget);
m_ensembleLegendWidgets[curveSetToShowLegendFor] = overlayWidget; m_ensembleLegendWidgets[curveSetToShowLegendFor] = overlayWidget;
} }
else else

View File

@ -24,12 +24,22 @@
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RiuWidgetDragger::RiuWidgetDragger(QWidget* widgetToMove) RiuWidgetDragger::RiuWidgetDragger(QWidget* widgetToMove, QWidget* widgetToSnapTo /*= nullptr*/, int snapMargins /*= 5*/)
: QObject(widgetToMove) : QObject(widgetToMove)
, m_widgetToMove(widgetToMove) , m_widgetToMove(widgetToMove)
, m_widgetToSnapTo(widgetToSnapTo)
, m_snapMargins(snapMargins)
, m_startPos(0,0) , m_startPos(0,0)
{ {
m_widgetToMove->installEventFilter(this); addWidget(m_widgetToMove);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWidgetDragger::addWidget(QWidget* widget)
{
widget->installEventFilter(this);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -42,13 +52,75 @@ bool RiuWidgetDragger::eventFilter(QObject * watched, QEvent * event)
QMouseEvent* mMoveEv = static_cast<QMouseEvent*>(event); QMouseEvent* mMoveEv = static_cast<QMouseEvent*>(event);
if (mMoveEv->buttons() & Qt::LeftButton) if (mMoveEv->buttons() & Qt::LeftButton)
{ {
m_widgetToMove->move( m_widgetToMove->mapToParent(mMoveEv->pos() - m_startPos)); QPoint relativeMove = mMoveEv->pos() - m_startPos;
QRect newFrameRect = m_widgetToMove->frameGeometry().translated(relativeMove);
if (m_widgetToSnapTo)
{
QRect snapToRect = m_widgetToSnapTo->frameGeometry();
{
QPoint snapToTopLeft = snapToRect.topLeft();
QPoint widgetTopLeft = newFrameRect.topLeft();
QPoint diff = snapToTopLeft - widgetTopLeft;
if (std::abs(diff.x()) < 4 * m_snapMargins)
{
newFrameRect.moveLeft(snapToTopLeft.x() + m_snapMargins);
}
if (std::abs(diff.y()) < 4 * m_snapMargins)
{
newFrameRect.moveTop(snapToTopLeft.y() + m_snapMargins);
}
}
{
QPoint snapToBottomLeft = snapToRect.bottomLeft();
QPoint widgetBottomLeft = newFrameRect.bottomLeft();
QPoint diff = snapToBottomLeft - widgetBottomLeft;
if (std::abs(diff.x()) < 4 * m_snapMargins)
{
newFrameRect.moveLeft(snapToBottomLeft.x() + m_snapMargins);
}
if (std::abs(diff.y()) < 4 * m_snapMargins)
{
newFrameRect.moveBottom(snapToBottomLeft.y() - m_snapMargins);
}
}
{
QPoint snapToTopRight = snapToRect.topRight();
QPoint widgetTopRight = newFrameRect.topRight();
QPoint diff = snapToTopRight - widgetTopRight;
if (std::abs(diff.x()) < 4 * m_snapMargins)
{
newFrameRect.moveRight(snapToTopRight.x() - m_snapMargins);
}
if (std::abs(diff.y()) < 4 * m_snapMargins)
{
newFrameRect.moveTop(snapToTopRight.y() + m_snapMargins);
}
}
{
QPoint snapToBottomRight = snapToRect.bottomRight();
QPoint widgetBottomRight = newFrameRect.bottomRight();
QPoint diff = snapToBottomRight - widgetBottomRight;
if (std::abs(diff.x()) < 4 * m_snapMargins)
{
newFrameRect.moveRight(snapToBottomRight.x() - m_snapMargins);
}
if (std::abs(diff.y()) < 4 * m_snapMargins)
{
newFrameRect.moveBottom(snapToBottomRight.y() - m_snapMargins);
}
}
}
m_widgetToMove->move(newFrameRect.topLeft());
return true;
} }
} }
else if (event->type() == QEvent::MouseButtonPress) else if (event->type() == QEvent::MouseButtonPress)
{ {
QMouseEvent* mEv = static_cast<QMouseEvent*>(event); QMouseEvent* mEv = static_cast<QMouseEvent*>(event);
m_startPos = mEv->pos(); m_startPos = mEv->pos();
return true;
} }
return false; return false;

View File

@ -28,13 +28,16 @@ class RiuWidgetDragger : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
RiuWidgetDragger(QWidget* widgetToMove); RiuWidgetDragger(QWidget* widgetToMove, QWidget* widgetToSnapTo = nullptr, int snapMargins = 5);
void addWidget(QWidget* widget);
bool eventFilter(QObject * watched, QEvent * event) override; bool eventFilter(QObject * watched, QEvent * event) override;
private: private:
QPointer<QWidget> m_widgetToMove; QPointer<QWidget> m_widgetToMove;
QPoint m_startPos; QPointer<QWidget> m_widgetToSnapTo;
int m_snapMargins;
QPoint m_startPos;
}; };