#2657 WIP: Add movable widget with color legend for ensemble curve sets to summary plot

This commit is contained in:
Jacob Støren
2018-04-18 15:58:49 +02:00
parent e468227dfe
commit 53a6e0e502
9 changed files with 443 additions and 0 deletions

View File

@@ -145,6 +145,13 @@ RimEnsambleCurveSet::RimEnsambleCurveSet()
RimEnsambleCurveSet::~RimEnsambleCurveSet()
{
m_curves.deleteAllChildObjects();
RimSummaryPlot* parentPlot;
firstAncestorOrThisOfTypeAsserted(parentPlot);
if (parentPlot->qwtPlot())
{
parentPlot->qwtPlot()->removeEnsambleCurveSetLegend(this);
}
}
//--------------------------------------------------------------------------------------------------
@@ -185,6 +192,15 @@ void RimEnsambleCurveSet::loadDataAndUpdate(bool updateParentPlot)
parentPlot->qwtPlot()->updateLegend();
parentPlot->updateAxes();
parentPlot->updateZoomInQwt();
if (m_showCurves() && m_colorMode() == BY_ENSAMBLE_PARAM)
{
parentPlot->qwtPlot()->addOrUpdateEnsambleCurveSetLegend(this);
}
else
{
parentPlot->qwtPlot()->removeEnsambleCurveSetLegend(this);
}
}
}
}
@@ -422,6 +438,14 @@ void RimEnsambleCurveSet::handleKeyPressEvent(QKeyEvent* keyEvent)
//}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimRegularLegendConfig* RimEnsambleCurveSet::legendConfig()
{
return m_legendConfig;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -79,6 +79,7 @@ public:
//std::vector<caf::PdmFieldHandle*> fieldsToShowInToolbar();
void handleKeyPressEvent(QKeyEvent* keyEvent);
RimRegularLegendConfig* legendConfig();
private:
caf::PdmFieldHandle* objectToggleField();

View File

@@ -21,6 +21,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotZoomer.h
${CMAKE_CURRENT_LIST_DIR}/RiuWidgetDragger.h
${CMAKE_CURRENT_LIST_DIR}/RiuCvfOverlayItemWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuRecentFileActionProvider.h
${CMAKE_CURRENT_LIST_DIR}/RiuRelativePermeabilityPlotPanel.h
${CMAKE_CURRENT_LIST_DIR}/RiuRelativePermeabilityPlotUpdater.h
@@ -90,6 +92,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotUpdater.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuWidgetDragger.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuCvfOverlayItemWidget.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuRecentFileActionProvider.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuRelativePermeabilityPlotPanel.cpp
${CMAKE_CURRENT_LIST_DIR}/RiuRelativePermeabilityPlotUpdater.cpp
@@ -165,6 +169,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuSummaryQwtPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuTofAccumulatedPhaseFractionsPlot.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.h
${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.h
${CMAKE_CURRENT_LIST_DIR}/RiuWidgetDragger.h
${CMAKE_CURRENT_LIST_DIR}/RiuCvfOverlayItemWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuEditPerforationCollectionWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuExportMultipleSnapshotsWidget.h
${CMAKE_CURRENT_LIST_DIR}/RiuWellAllocationPlot.h

View File

@@ -0,0 +1,210 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil 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 "RiuCvfOverlayItemWidget.h"
#include <QApplication>
#include <QFrame>
#include <QLabel>
#include <QPixmap>
#include <QPushButton>
#include <QResizeEvent>
#include <QBoxLayout>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget(QWidget* parent/*=0*/)
: QWidget(parent)
{
this->setLayout(new QHBoxLayout(this));
m_overlayItemLabel = new QLabel(this);
this->layout()->addWidget(m_overlayItemLabel);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuCvfOverlayItemWidget::~RiuCvfOverlayItemWidget()
{
}
#include "cafViewer.h"
#include "cvfRendering.h"
#include "cvfRenderSequence.h"
#include "cvfFramebufferObject.h"
#include "cvfRenderbufferObject.h"
#include "cvfqtUtils.h"
#include "glew/GL/glew.h"
#include "RiaApplication.h"
#include "cvfCamera.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuCvfOverlayItemWidget::updateFromOverlyItem( cvf::OverlayItem * item)
{
//m_scalarMapperLegend->setTitle("Hei og hopp");
//m_scalarMapperLegend->computeLayoutAndExtents({0,0}, {100, 400});
//unsigned int width = m_scalarMapperLegend->minimumWidth() + 100;
unsigned int width = item->sizeHint().x();
unsigned int height = item->sizeHint().y();
QGLFormat glFormat;
glFormat.setDirectRendering(RiaApplication::instance()->useShaders());
caf::Viewer* viewer = new caf::Viewer(glFormat, nullptr);
cvf::OpenGLContext* cvfOglContext = viewer->cvfOpenGLContext();
viewer->resize(width, height);
// Create a rendering
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
item->setLayoutFixedPosition({0,0});
rendering->addOverlayItem(item);
rendering->camera()->setViewport(0,0,width, height);
rendering->camera()->viewport()->setClearColor({1,1,1,0});
cvf::ref<cvf::RenderSequence> renderingSequence = new cvf::RenderSequence;
renderingSequence->addRendering(rendering.p());
if (RiaApplication::instance()->useShaders())
{
// Set up frame and render buffers
cvf::ref<cvf::FramebufferObject> fbo = new cvf::FramebufferObject;
cvf::ref<cvf::RenderbufferObject> rboColor = new cvf::RenderbufferObject(cvf::RenderbufferObject::RGBA, width, height);
cvf::ref<cvf::RenderbufferObject> rboDepth = new cvf::RenderbufferObject(cvf::RenderbufferObject::DEPTH_COMPONENT24, width, height);
fbo->attachDepthRenderbuffer(rboDepth.p());
fbo->attachColorRenderbuffer(0, rboColor.p());
fbo->applyOpenGL(cvfOglContext);
rendering->setTargetFramebuffer(fbo.p());
fbo->bind(cvfOglContext);
}
renderingSequence->render(cvfOglContext);
// Read data from framebuffer
cvf::UByteArray arr(4*width*height);
glReadPixels(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height), GL_RGBA, GL_UNSIGNED_BYTE, arr.ptr());
// Create a cvf texture image
cvf::ref<cvf::TextureImage> img = new cvf::TextureImage;
img->setData(arr.ptr(), width, height);
QImage image = cvfqt::Utils::toQImage(*img.p());
//image.save("jjsLegendImageTest.png");
QPixmap pixmap = QPixmap::fromImage(image);
delete viewer;
m_overlayItemLabel->setPixmap(pixmap);
this->setMinimumSize(QSize(width, height));
}
#if 0
#include "cafViewer.h"
#include "cvfRendering.h"
#include "cvfRenderSequence.h"
#include "cvfFramebufferObject.h"
#include "cvfRenderbufferObject.h"
#include "cvfqtUtils.h"
#include "glew/GL/glew.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPixmap RimLegendConfig::drawLegend()
{
m_scalarMapperLegend->setTitle("Hei og hopp");
m_scalarMapperLegend->computeLayoutAndExtents({0,0}, {100, 400});
unsigned int width = m_scalarMapperLegend->minimumWidth() + 100;
unsigned int height = m_scalarMapperLegend->sizeHint().y();
QGLFormat glFormat;
glFormat.setDirectRendering(RiaApplication::instance()->useShaders());
caf::Viewer* viewer = new caf::Viewer(glFormat, nullptr);
cvf::OpenGLContext* cvfOglContext = viewer->cvfOpenGLContext();
viewer->resize(width, height);
// Create a rendering
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
m_scalarMapperLegend->setLayoutFixedPosition({0,0});
rendering->addOverlayItem(m_scalarMapperLegend.p());
rendering->camera()->setViewport(0,0,width, height);
rendering->camera()->viewport()->setClearColor({1,1,1,0});
cvf::ref<cvf::RenderSequence> renderingSequence = new cvf::RenderSequence;
renderingSequence->addRendering(rendering.p());
if (RiaApplication::instance()->useShaders())
{
// Set up frame and render buffers
cvf::ref<cvf::FramebufferObject> fbo = new cvf::FramebufferObject;
cvf::ref<cvf::RenderbufferObject> rboColor = new cvf::RenderbufferObject(cvf::RenderbufferObject::RGBA, width, height);
cvf::ref<cvf::RenderbufferObject> rboDepth = new cvf::RenderbufferObject(cvf::RenderbufferObject::DEPTH_COMPONENT24, width, height);
fbo->attachDepthRenderbuffer(rboDepth.p());
fbo->attachColorRenderbuffer(0, rboColor.p());
fbo->applyOpenGL(cvfOglContext);
rendering->setTargetFramebuffer(fbo.p());
fbo->bind(cvfOglContext);
}
renderingSequence->render(cvfOglContext);
// Read data from framebuffer
cvf::UByteArray arr(4*width*height);
glReadPixels(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height), GL_RGBA, GL_UNSIGNED_BYTE, arr.ptr());
// Create a cvf texture image
cvf::ref<cvf::TextureImage> img = new cvf::TextureImage;
img->setData(arr.ptr(), width, height);
QImage image = cvfqt::Utils::toQImage(*img.p());
//image.save("jjsLegendImageTest.png");
QPixmap pixmap = QPixmap::fromImage(image);
delete viewer;
return pixmap;
}
#endif

View File

@@ -0,0 +1,48 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil 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 <QWidget>
class QLabel;
namespace cvf
{
class OverlayItem;
}
//==================================================================================================
//
//
//
//==================================================================================================
class RiuCvfOverlayItemWidget : public QWidget
{
Q_OBJECT
public:
explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr);
~RiuCvfOverlayItemWidget();
void updateFromOverlyItem( cvf::OverlayItem * item);
// virtual QSize sizeHint() const override;
// virtual QSize minimumSizeHint() const override;
protected:
QLabel* m_overlayItemLabel;
};

View File

@@ -52,6 +52,12 @@
#include <float.h>
#include "RiuWidgetDragger.h"
#include "RiuCvfOverlayItemWidget.h"
#include "RimEnsambleCurveSet.h"
#include "RimRegularLegendConfig.h"
#include "cafTitledOverlayFrame.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -158,6 +164,48 @@ void RiuSummaryQwtPlot::setZoomWindow(const QwtInterval& leftAxis, const QwtInte
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::addOrUpdateEnsambleCurveSetLegend(RimEnsambleCurveSet * curveSetToShowLegendFor)
{
RiuCvfOverlayItemWidget* overlayWidget = nullptr;
auto it = m_ensembleLegendWidgets.find(curveSetToShowLegendFor);
if (it == m_ensembleLegendWidgets.end() || it->second == nullptr)
{
overlayWidget = new RiuCvfOverlayItemWidget(this);
new RiuWidgetDragger(overlayWidget);
m_ensembleLegendWidgets[curveSetToShowLegendFor] = overlayWidget;
overlayWidget->move(30, 30);
}
else
{
overlayWidget = it->second;
}
if ( overlayWidget )
{
overlayWidget->updateFromOverlyItem(curveSetToShowLegendFor->legendConfig()->titledOverlayFrame());
overlayWidget->show();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryQwtPlot::removeEnsambleCurveSetLegend(RimEnsambleCurveSet * curveSetToShowLegendFor)
{
auto it = m_ensembleLegendWidgets.find(curveSetToShowLegendFor);
if ( it != m_ensembleLegendWidgets.end() )
{
if ( it->second != nullptr ) it->second->deleteLater();
m_ensembleLegendWidgets.erase(it);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -32,8 +32,12 @@ class QwtPlotZoomer;
class QwtInterval;
class QwtPicker;
class QwtPlotMarker;
class QwtScaleWidget;
class RiuCvfOverlayItemWidget;
class RimSummaryPlot;
class RimEnsambleCurveSet;
//==================================================================================================
//
@@ -61,6 +65,9 @@ public:
const QwtInterval& rightAxis,
const QwtInterval& timeAxis);
void addOrUpdateEnsambleCurveSetLegend(RimEnsambleCurveSet * curveSetToShowLegendFor);
void removeEnsambleCurveSetLegend(RimEnsambleCurveSet * curveSetToShowLegendFor);
static void setCommonPlotBehaviour(QwtPlot* plot);
static void enableDateBasedBottomXAxis(QwtPlot* plot);
@@ -85,5 +92,8 @@ private:
QPointer<QwtPlotZoomer> m_zoomerLeft;
QPointer<QwtPlotZoomer> m_zoomerRight;
std::map< caf::PdmPointer<RimEnsambleCurveSet>, QPointer<RiuCvfOverlayItemWidget> > m_ensembleLegendWidgets;
};

View File

@@ -0,0 +1,56 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil 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 "RiuWidgetDragger.h"
#include <QEvent>
#include <QWidget>
#include <QMouseEvent>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWidgetDragger::RiuWidgetDragger(QWidget* widgetToMove)
: QObject(widgetToMove)
, m_widgetToMove(widgetToMove)
, m_startPos(0,0)
{
m_widgetToMove->installEventFilter(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWidgetDragger::eventFilter(QObject * watched, QEvent * event)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent* mMoveEv = static_cast<QMouseEvent*>(event);
if (mMoveEv->buttons() & Qt::LeftButton)
{
m_widgetToMove->move( m_widgetToMove->mapToParent(mMoveEv->pos() - m_startPos));
}
}
else if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mEv = static_cast<QMouseEvent*>(event);
m_startPos = mEv->pos();
}
return false;
}

View File

@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- Statoil 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 <QObject>
#include <QPointer>
#include <QPoint>
class QWidget;
class QEvent;
class RiuWidgetDragger : public QObject
{
Q_OBJECT
public:
RiuWidgetDragger(QWidget* widgetToMove);
virtual bool eventFilter(QObject * watched, QEvent * event) override;
private:
QPointer<QWidget> m_widgetToMove;
QPoint m_startPos;
};