mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4158 Implement info box for grid cross plots and improve plot overlay legends
This commit is contained in:
@@ -80,6 +80,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMeasurementViewEventFilter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
|
||||
)
|
||||
|
||||
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}/RiuQwtPlotTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.cpp
|
||||
)
|
||||
|
||||
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}/RiuCalculationsContextMenuManager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
|
||||
)
|
||||
|
||||
list(APPEND QT_UI_FILES
|
||||
|
||||
@@ -41,16 +41,11 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget(QWidget* parent/*=0*/)
|
||||
: QWidget(parent)
|
||||
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget(QWidget* parent/*=0*/, QWidget* widgetToSnapTo)
|
||||
: RiuDraggableOverlayFrame(parent, widgetToSnapTo)
|
||||
{
|
||||
auto hblayout = new QHBoxLayout(this);
|
||||
hblayout->setMargin(0);
|
||||
hblayout->setSpacing(0);
|
||||
|
||||
this->setLayout(hblayout);
|
||||
m_overlayItemLabel = new QLabel(this);
|
||||
this->layout()->addWidget(m_overlayItemLabel);
|
||||
this->layout()->setMargin(0);
|
||||
this->layout()->setSpacing(0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -126,7 +121,7 @@ void RiuCvfOverlayItemWidget::updateFromOverlayItem( cvf::OverlayItem * item)
|
||||
QPixmap pixmap = QPixmap::fromImage(image);
|
||||
|
||||
delete viewer;
|
||||
|
||||
|
||||
m_overlayItemLabel->setPixmap(pixmap);
|
||||
this->setMinimumSize(QSize(width, height));
|
||||
this->resize(QSize(width, height));
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
@@ -31,18 +33,15 @@ namespace cvf
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiuCvfOverlayItemWidget : public QWidget
|
||||
class RiuCvfOverlayItemWidget : public RiuDraggableOverlayFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr);
|
||||
explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr, QWidget* widgetToSnapTo = nullptr);
|
||||
~RiuCvfOverlayItemWidget() override;
|
||||
|
||||
void updateFromOverlayItem( cvf::OverlayItem * item);
|
||||
|
||||
// virtual QSize sizeHint() const override;
|
||||
// virtual QSize minimumSizeHint() const override;
|
||||
|
||||
protected:
|
||||
QLabel* m_overlayItemLabel;
|
||||
};
|
||||
|
||||
61
ApplicationCode/UserInterface/RiuDraggableOverlayFrame.cpp
Normal file
61
ApplicationCode/UserInterface/RiuDraggableOverlayFrame.cpp
Normal 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;
|
||||
}
|
||||
35
ApplicationCode/UserInterface/RiuDraggableOverlayFrame.h
Normal file
35
ApplicationCode/UserInterface/RiuDraggableOverlayFrame.h
Normal 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;
|
||||
};
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "RimPlotAxisProperties.h"
|
||||
#include "RiuPlotAnnotationTool.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QResizeEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -42,6 +44,7 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot(RimViewWindow* ownerViewWindow, QWidget
|
||||
: RiuQwtPlot(ownerViewWindow, parent)
|
||||
{
|
||||
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);
|
||||
if (it == m_legendWidgets.end() || it->second == nullptr)
|
||||
{
|
||||
overlayWidget = new RiuCvfOverlayItemWidget(this);
|
||||
|
||||
new RiuWidgetDragger(overlayWidget);
|
||||
|
||||
overlayWidget = new RiuCvfOverlayItemWidget(this, canvas());
|
||||
m_legendWidgets[curveSet] = overlayWidget;
|
||||
}
|
||||
else
|
||||
@@ -144,9 +144,66 @@ void RiuGridCrossQwtPlot::updateAnnotationObjects(RimPlotAxisProperties* axisPro
|
||||
void RiuGridCrossQwtPlot::updateLayout()
|
||||
{
|
||||
QwtPlot::updateLayout();
|
||||
updateInfoBoxLayout();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
class RimGridCrossPlotCurveSet;
|
||||
class RiuCvfOverlayItemWidget;
|
||||
class RiuDraggableOverlayFrame;
|
||||
class RiuPlotAnnotationTool;
|
||||
class RimPlotAxisProperties;
|
||||
|
||||
@@ -55,12 +56,18 @@ public:
|
||||
|
||||
protected:
|
||||
void updateLayout() override;
|
||||
void updateInfoBoxLayout();
|
||||
void updateLegendLayout();
|
||||
void resizeEvent(QResizeEvent* e) override;
|
||||
bool resizeOverlayItemToFitPlot(caf::TitledOverlayFrame* overlayItem);
|
||||
void contextMenuEvent(QContextMenuEvent*) override;
|
||||
|
||||
private:
|
||||
std::map<caf::PdmPointer<RimGridCrossPlotCurveSet>, QPointer<RiuCvfOverlayItemWidget>> m_legendWidgets;
|
||||
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
|
||||
typedef caf::PdmPointer<RimGridCrossPlotCurveSet> CurveSetPtr;
|
||||
typedef QPointer<RiuCvfOverlayItemWidget> LegendPtr;
|
||||
typedef QPointer<RiuDraggableOverlayFrame> InfoBoxPtr;
|
||||
|
||||
InfoBoxPtr m_infoBox;
|
||||
std::map<CurveSetPtr, LegendPtr> m_legendWidgets;
|
||||
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
|
||||
};
|
||||
|
||||
@@ -123,10 +123,7 @@ void RiuSummaryQwtPlot::addOrUpdateEnsembleCurveSetLegend(RimEnsembleCurveSet* c
|
||||
auto it = m_ensembleLegendWidgets.find(curveSetToShowLegendFor);
|
||||
if (it == m_ensembleLegendWidgets.end() || it->second == nullptr)
|
||||
{
|
||||
overlayWidget = new RiuCvfOverlayItemWidget(this);
|
||||
|
||||
new RiuWidgetDragger(overlayWidget);
|
||||
|
||||
overlayWidget = new RiuCvfOverlayItemWidget(this, canvas());
|
||||
m_ensembleLegendWidgets[curveSetToShowLegendFor] = overlayWidget;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -24,12 +24,22 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuWidgetDragger::RiuWidgetDragger(QWidget* widgetToMove)
|
||||
RiuWidgetDragger::RiuWidgetDragger(QWidget* widgetToMove, QWidget* widgetToSnapTo /*= nullptr*/, int snapMargins /*= 5*/)
|
||||
: QObject(widgetToMove)
|
||||
, m_widgetToMove(widgetToMove)
|
||||
, m_widgetToSnapTo(widgetToSnapTo)
|
||||
, m_snapMargins(snapMargins)
|
||||
, 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);
|
||||
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)
|
||||
{
|
||||
QMouseEvent* mEv = static_cast<QMouseEvent*>(event);
|
||||
m_startPos = mEv->pos();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -28,13 +28,16 @@ class RiuWidgetDragger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RiuWidgetDragger(QWidget* widgetToMove);
|
||||
RiuWidgetDragger(QWidget* widgetToMove, QWidget* widgetToSnapTo = nullptr, int snapMargins = 5);
|
||||
|
||||
void addWidget(QWidget* widget);
|
||||
bool eventFilter(QObject * watched, QEvent * event) override;
|
||||
|
||||
private:
|
||||
QPointer<QWidget> m_widgetToMove;
|
||||
QPoint m_startPos;
|
||||
QPointer<QWidget> m_widgetToSnapTo;
|
||||
int m_snapMargins;
|
||||
QPoint m_startPos;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user