From aee42f403b3c2a8ea5f40f5cf1f2a63801291e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Fri, 11 Oct 2019 09:12:58 +0200 Subject: [PATCH] #4849 RiuViewer: Add support for a comparison gridbox Add support for controlling the Comparison view window Use overlay rendering for overlay items Add a removeColorLegend method Update overlay positioning on each redraw --- .../UserInterface/CMakeLists_files.cmake | 2 + .../UserInterface/RiuComparisonViewMover.cpp | 147 ++++++++++++++++++ .../UserInterface/RiuComparisonViewMover.h | 58 +++++++ ApplicationCode/UserInterface/RiuViewer.cpp | 90 ++++++----- ApplicationCode/UserInterface/RiuViewer.h | 10 +- 5 files changed, 270 insertions(+), 37 deletions(-) create mode 100644 ApplicationCode/UserInterface/RiuComparisonViewMover.cpp create mode 100644 ApplicationCode/UserInterface/RiuComparisonViewMover.h diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index d094e4d033..4aaa08a96c 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -83,6 +83,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuMeasurementViewEventFilter.h ${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h ${CMAKE_CURRENT_LIST_DIR}/RiuMdiMaximizeWindowGuard.h ${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowTools.h +${CMAKE_CURRENT_LIST_DIR}/RiuComparisonViewMover.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -165,6 +166,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuMdiMaximizeWindowGuard.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuComparisonViewMover.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/UserInterface/RiuComparisonViewMover.cpp b/ApplicationCode/UserInterface/RiuComparisonViewMover.cpp new file mode 100644 index 0000000000..1bdd16c323 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuComparisonViewMover.cpp @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RiuComparisonViewMover.h" + +#include "cafViewer.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuComparisonViewMover::RiuComparisonViewMover( caf::Viewer* viewer ) + : QObject( viewer ) + , m_viewer( viewer ) + , m_dragState( NONE ) + , m_highlightHandle( NONE ) +{ + viewer->installEventFilter( this ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuComparisonViewMover::eventFilter( QObject* watched, QEvent* event ) +{ + if ( !m_viewer->currentScene( true ) ) return false; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + { + QMouseEvent* mEv = static_cast( event ); + + if ( mEv->type() == QEvent::MouseButtonPress && mEv->button() == Qt::LeftButton ) + { + DragState handle = findHandleUnderMouse( mEv->pos() ); + m_dragState = handle; + } + else if ( mEv->type() == QEvent::MouseButtonRelease && mEv->button() == Qt::LeftButton ) + { + m_dragState = NONE; + } + else if ( mEv->type() == QEvent::MouseMove ) + { + m_highlightHandle = findHandleUnderMouse( mEv->pos() ); + + if ( m_dragState == LEFT_EDGE ) + { + QPointF mousePos = mEv->windowPos(); + QPointF normMousePos = {mousePos.x() / m_viewer->width(), mousePos.y() / m_viewer->height()}; + cvf::Rectf orgCompViewWindow = m_viewer->comparisonViewVisibleNormalizedRect(); + + m_viewer->setComparisonViewVisibleNormalizedRect( + cvf::Rectf( normMousePos.x(), + orgCompViewWindow.min().y(), + ( orgCompViewWindow.min().x() + orgCompViewWindow.width() ) - + normMousePos.x(), + orgCompViewWindow.height() ) ); + + return true; + } + else + { + m_viewer->update(); + } + } + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuComparisonViewMover::paintMoverHandles( QPainter* painter ) +{ + if ( !m_viewer->currentScene( true ) ) return; + + const int handleThickness = 7; + cvf::Rectf normalizedComparisonRect = m_viewer->comparisonViewVisibleNormalizedRect(); + int viewerWidth = m_viewer->width(); + int viewerHeight = m_viewer->height(); + + int leftEdgePos = viewerWidth * normalizedComparisonRect.min().x(); + int width = viewerWidth * normalizedComparisonRect.width(); + int height = viewerHeight * normalizedComparisonRect.height(); + int topEdgePosOgl = viewerHeight * normalizedComparisonRect.max().y(); + int topEdgePosQt = height - topEdgePosOgl; + int bottomEdgePosQt = height - viewerHeight * normalizedComparisonRect.min().y(); + + painter->setPen( QColor( 0, 0, 0, 30 ) ); + + painter->drawRect( leftEdgePos, topEdgePosQt, width - 1, height - 1 ); + + QColor handleColor( 0, 0, 0, 50 ); + if ( m_highlightHandle == LEFT_EDGE || m_dragState == LEFT_EDGE ) + { + handleColor = QColor( 255, 255, 255, 50 ); + } + + painter->fillRect( leftEdgePos - handleThickness * 0.4, + bottomEdgePosQt - 8 * handleThickness, + handleThickness, + handleThickness * 6, + handleColor ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuComparisonViewMover::DragState RiuComparisonViewMover::findHandleUnderMouse( const QPoint& mousePos ) +{ + const int handleThickness = 7; + cvf::Rectf normalizedComparisonRect = m_viewer->comparisonViewVisibleNormalizedRect(); + int viewerWidth = m_viewer->width(); + int viewerHeight = m_viewer->height(); + + int leftEdgePos = viewerWidth * normalizedComparisonRect.min().x(); + int height = viewerHeight * normalizedComparisonRect.height(); + int bottomEdgePosQt = height - viewerHeight * normalizedComparisonRect.min().y(); + + if ( ( leftEdgePos - handleThickness * 0.4 ) < mousePos.x() && + mousePos.x() < ( leftEdgePos + handleThickness * 0.5 ) && + ( bottomEdgePosQt - 8 * handleThickness ) < mousePos.y() && + mousePos.y() < ( bottomEdgePosQt - 2 * handleThickness ) ) + { + return LEFT_EDGE; + } + + return NONE; +} diff --git a/ApplicationCode/UserInterface/RiuComparisonViewMover.h b/ApplicationCode/UserInterface/RiuComparisonViewMover.h new file mode 100644 index 0000000000..275e342166 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuComparisonViewMover.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include + +#include +#include + +namespace caf +{ +class Viewer; +} + +class RiuComparisonViewMover : public QObject +{ +public: + RiuComparisonViewMover( caf::Viewer* viewer ); + + virtual bool eventFilter( QObject* watched, QEvent* event ) override; + + void paintMoverHandles( QPainter* painter ); + +private: + enum DragState + { + NONE, + COMPLETE_BOX, + LEFT_EDGE, + RIGHT_EDGE, + TOP_EDGE, + BOTTOM_EDGE, + }; + + DragState findHandleUnderMouse( const QPoint& mousePos ); + + QPointer m_viewer; + DragState m_dragState; + DragState m_highlightHandle; +}; diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index ef9f5b7446..92df8e6cb2 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -37,6 +37,7 @@ #include "WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h" #include "RiuCadNavigation.h" +#include "RiuComparisonViewMover.h" #include "RiuGeoQuestNavigation.h" #include "RiuRmsNavigation.h" #include "RiuSimpleHistogramWidget.h" @@ -101,7 +102,7 @@ RiuViewer::RiuViewer( const QGLFormat& format, QWidget* parent ) m_axisCross = new cvf::OverlayAxisCross( m_mainCamera.p(), standardFont ); m_axisCross->setAxisLabels( "X", "Y", "Z" ); m_axisCross->setLayout( cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_RIGHT ); - m_mainRendering->addOverlayItem( m_axisCross.p() ); + overlayItemsRendering()->addOverlayItem( m_axisCross.p() ); m_showAxisCross = true; this->enableOverlayPainting( true ); @@ -168,7 +169,8 @@ RiuViewer::RiuViewer( const QGLFormat& format, QWidget* parent ) // which solves the problem setContextMenuPolicy( Qt::PreventContextMenu ); - m_gridBoxGenerator = new RivGridBoxGenerator; + m_gridBoxGenerator = new RivGridBoxGenerator; + m_comparisonGridBoxGenerator = new RivGridBoxGenerator; m_cursorPositionDomainCoords = cvf::Vec3d::UNDEFINED; m_windowEdgeAxisOverlay = new RivWindowEdgeAxesOverlayItem( standardFont ); @@ -178,6 +180,8 @@ RiuViewer::RiuViewer( const QGLFormat& format, QWidget* parent ) m_scaleLegend = new caf::OverlayScaleLegend( standardFont ); m_scaleLegend->setOrientation( caf::OverlayScaleLegend::HORIZONTAL ); + + m_comparisonWindowMover = new RiuComparisonViewMover( this ); } //-------------------------------------------------------------------------------------------------- @@ -195,6 +199,7 @@ RiuViewer::~RiuViewer() delete m_animationProgress; delete m_histogramWidget; delete m_gridBoxGenerator; + delete m_comparisonGridBoxGenerator; } //-------------------------------------------------------------------------------------------------- @@ -333,19 +338,15 @@ void RiuViewer::setOwnerReservoirView( RiuViewerToViewInterface* owner ) m_viewerCommands->setOwnerView( dynamic_cast( owner ) ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuViewer::setEnableMask( unsigned int mask ) -{ - m_mainRendering->setEnableMask( mask ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuViewer::paintOverlayItems( QPainter* painter ) { + // Update the legend layout on every redraw as the legends stores their own position, + // and when they are shared between views the positions are overwritten. + updateLegendLayout(); + int columnWidth = 200; int edgeAxisFrameBorderWidth = m_showWindowEdgeAxes ? m_windowEdgeAxisOverlay->frameBorderWidth() : 0; @@ -443,6 +444,8 @@ void RiuViewer::paintOverlayItems( QPainter* painter ) } } } + + m_comparisonWindowMover->paintMoverHandles( painter ); } //-------------------------------------------------------------------------------------------------- @@ -516,10 +519,12 @@ void RiuViewer::setHistogramPercentiles( double pmin, double pmax, double mean ) void RiuViewer::showGridBox( bool enable ) { this->removeStaticModel( m_gridBoxGenerator->model() ); + this->removeStaticModel( m_comparisonGridBoxGenerator->model() ); if ( enable ) { - this->addStaticModelOnce( m_gridBoxGenerator->model() ); + this->addStaticModelOnce( m_gridBoxGenerator->model(), false ); + this->addStaticModelOnce( m_comparisonGridBoxGenerator->model(), true ); } } @@ -554,7 +559,7 @@ void RiuViewer::removeAllColorLegends() { for ( size_t i = 0; i < m_visibleLegends.size(); i++ ) { - m_mainRendering->removeOverlayItem( m_visibleLegends[i].p() ); + overlayItemsRendering()->removeOverlayItem( m_visibleLegends[i].p() ); } m_visibleLegends.clear(); @@ -567,10 +572,10 @@ void RiuViewer::addColorLegendToBottomLeftCorner( caf::TitledOverlayFrame* added { RiaGuiApplication* app = RiaGuiApplication::instance(); CVF_ASSERT( app ); - RiaPreferences* preferences = app->preferences(); - cvf::Rendering* firstRendering = m_mainRendering.p(); + RiaPreferences* preferences = app->preferences(); + cvf::Rendering* overlayRendering = overlayItemsRendering(); CVF_ASSERT( preferences ); - CVF_ASSERT( firstRendering ); + CVF_ASSERT( overlayRendering ); if ( addedLegend ) { @@ -579,17 +584,27 @@ void RiuViewer::addColorLegendToBottomLeftCorner( caf::TitledOverlayFrame* added cvf::Color3f frameColor( backgroundColor.r(), backgroundColor.g(), backgroundColor.b() ); updateLegendTextAndTickMarkColor( addedLegend ); - firstRendering->addOverlayItem( addedLegend ); + overlayRendering->addOverlayItem( addedLegend ); addedLegend->enableBackground( preferences->showLegendBackground() ); addedLegend->setBackgroundColor( backgroundColor ); addedLegend->setBackgroundFrameColor( cvf::Color4f( RiaColorTools::computeOffsetColor( frameColor, 0.3f ), 0.9f ) ); addedLegend->setFont( app->defaultSceneFont() ); - m_visibleLegends.push_back( addedLegend ); + if ( !m_visibleLegends.contains( addedLegend ) ) + { + m_visibleLegends.push_back( addedLegend ); + } } +} - updateLegendLayout(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::removeColorLegend( caf::TitledOverlayFrame* legend ) +{ + overlayItemsRendering()->removeOverlayItem( legend ); + m_visibleLegends.erase( legend ); } //-------------------------------------------------------------------------------------------------- @@ -759,11 +774,11 @@ void RiuViewer::setCurrentFrame( int frameIndex ) //-------------------------------------------------------------------------------------------------- void RiuViewer::showAxisCross( bool enable ) { - m_mainRendering->removeOverlayItem( m_axisCross.p() ); + overlayItemsRendering()->removeOverlayItem( m_axisCross.p() ); if ( enable ) { - m_mainRendering->addOverlayItem( m_axisCross.p() ); + overlayItemsRendering()->addOverlayItem( m_axisCross.p() ); } m_showAxisCross = enable; } @@ -796,6 +811,7 @@ void RiuViewer::optimizeClippingPlanes() } m_gridBoxGenerator->updateFromCamera( mainCamera() ); + m_comparisonGridBoxGenerator->updateFromCamera( comparisonMainCamera() ); m_scaleLegend->setDisplayCoordTransform( m_rimView->displayCoordTransform().p() ); m_scaleLegend->updateFromCamera( mainCamera() ); @@ -809,7 +825,6 @@ void RiuViewer::optimizeClippingPlanes() void RiuViewer::resizeGL( int width, int height ) { caf::Viewer::resizeGL( width, height ); - this->updateLegendLayout(); } //-------------------------------------------------------------------------------------------------- @@ -892,6 +907,17 @@ void RiuViewer::updateGridBoxData( double scaleZ, m_gridBoxGenerator->createGridBoxParts(); + m_comparisonGridBoxGenerator->setScaleZ( scaleZ ); + cvf::Vec3d unscaledComparisonOffset = comparisonViewEyePointOffset(); + + unscaledComparisonOffset.z() /= scaleZ; + + m_comparisonGridBoxGenerator->setDisplayModelOffset( displayModelOffset - unscaledComparisonOffset ); + m_comparisonGridBoxGenerator->updateFromBackgroundColor( backgroundColor ); + m_comparisonGridBoxGenerator->setGridBoxDomainCoordBoundingBox( domainCoordBoundingBox ); + + m_comparisonGridBoxGenerator->createGridBoxParts(); + m_selectionVisualizerManager->updateVisibleEditors(); } @@ -900,19 +926,17 @@ void RiuViewer::updateGridBoxData( double scaleZ, //-------------------------------------------------------------------------------------------------- void RiuViewer::showEdgeTickMarksXY( bool enable, bool showAxisLines ) { - m_mainRendering->removeOverlayItem( m_windowEdgeAxisOverlay.p() ); + overlayItemsRendering()->removeOverlayItem( m_windowEdgeAxisOverlay.p() ); if ( enable ) { m_windowEdgeAxisOverlay->setDomainAxes( RivWindowEdgeAxesOverlayItem::XY_AXES ); m_windowEdgeAxisOverlay->setIsSwitchingYAxisSign( false ); m_windowEdgeAxisOverlay->setShowAxisLines( showAxisLines ); - m_mainRendering->addOverlayItem( m_windowEdgeAxisOverlay.p() ); + overlayItemsRendering()->addOverlayItem( m_windowEdgeAxisOverlay.p() ); } m_showWindowEdgeAxes = enable; - - updateLegendLayout(); } //-------------------------------------------------------------------------------------------------- @@ -920,19 +944,17 @@ void RiuViewer::showEdgeTickMarksXY( bool enable, bool showAxisLines ) //-------------------------------------------------------------------------------------------------- void RiuViewer::showEdgeTickMarksXZ( bool enable, bool showAxisLines ) { - m_mainRendering->removeOverlayItem( m_windowEdgeAxisOverlay.p() ); + overlayItemsRendering()->removeOverlayItem( m_windowEdgeAxisOverlay.p() ); if ( enable ) { m_windowEdgeAxisOverlay->setDomainAxes( RivWindowEdgeAxesOverlayItem::XZ_AXES ); m_windowEdgeAxisOverlay->setIsSwitchingYAxisSign( true ); m_windowEdgeAxisOverlay->setShowAxisLines( showAxisLines ); - m_mainRendering->addOverlayItem( m_windowEdgeAxisOverlay.p() ); + overlayItemsRendering()->addOverlayItem( m_windowEdgeAxisOverlay.p() ); } m_showWindowEdgeAxes = enable; - - updateLegendLayout(); } //-------------------------------------------------------------------------------------------------- @@ -1043,14 +1065,12 @@ void RiuViewer::showScaleLegend( bool show ) else m_scaleLegend->setRenderSize( {50, 280} ); - m_mainRendering->addOverlayItem( m_scaleLegend.p() ); + overlayItemsRendering()->addOverlayItem( m_scaleLegend.p() ); } else { - m_mainRendering->removeOverlayItem( m_scaleLegend.p() ); + overlayItemsRendering()->removeOverlayItem( m_scaleLegend.p() ); } - - updateLegendLayout(); } //-------------------------------------------------------------------------------------------------- @@ -1075,12 +1095,12 @@ void RiuViewer::clearHoverCursor() void RiuViewer::updateFonts() { cvf::Font* standardFont = RiaGuiApplication::instance()->defaultSceneFont(); - m_mainRendering->removeOverlayItem( m_axisCross.p() ); + overlayItemsRendering()->removeOverlayItem( m_axisCross.p() ); m_axisCross = new cvf::OverlayAxisCross( m_mainCamera.p(), standardFont ); m_axisCross->setAxisLabels( "X", "Y", "Z" ); m_axisCross->setLayout( cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_RIGHT ); - m_mainRendering->addOverlayItem( m_axisCross.p() ); + overlayItemsRendering()->addOverlayItem( m_axisCross.p() ); m_showAxisCross = true; QFont font = QApplication::font(); diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index 31f2581e02..729fc1c518 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -40,6 +40,8 @@ class RiuViewerCommands; class RivGridBoxGenerator; class RivWindowEdgeAxesOverlayItem; +class RiuComparisonViewMover; + class QLabel; namespace caf @@ -79,7 +81,6 @@ public: void setOwnerReservoirView( RiuViewerToViewInterface* owner ); RiuViewerToViewInterface* ownerReservoirView(); RimViewWindow* ownerViewWindow() const override; - void setEnableMask( unsigned int mask ); void showInfoText( bool enable ); void showVersionInfo( bool enable ); @@ -107,6 +108,7 @@ public: void removeAllColorLegends(); void addColorLegendToBottomLeftCorner( caf::TitledOverlayFrame* legend ); + void removeColorLegend( caf::TitledOverlayFrame* legend ); void enableNavigationRotation( bool disable ); void updateNavigationPolicy(); @@ -185,7 +187,9 @@ private: RiuViewerCommands* m_viewerCommands; - RivGridBoxGenerator* m_gridBoxGenerator; + RivGridBoxGenerator* m_gridBoxGenerator; + RivGridBoxGenerator* m_comparisonGridBoxGenerator; + cvf::ref m_windowEdgeAxisOverlay; bool m_showWindowEdgeAxes; @@ -197,4 +201,6 @@ private: cvf::ref m_scaleLegend; static std::unique_ptr s_hoverCursor; + + RiuComparisonViewMover* m_comparisonWindowMover; };