mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Implement pdf rendering (#5250)
* First PDF creation support * Reimplement info box * Set title and make overlay frame margins more unified * Remove a style sheet that was never meant to be applied to Project Tree * Update RiuDraggableOverlayFrame when changing content * Default page layout in Preferences * undo removal of elision * Remove friend class assignment in cafCategoryMapper * the required methods have been made public * Fix up after review * Remove spurious const on by-value return * Fix compile errors on Linux * Fix size adjustment of legends with plot resizing
This commit is contained in:
@@ -87,6 +87,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMdiMaximizeWindowGuard.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuComparisonViewMover.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractOverlayContentFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractLegendFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuCategoryLegendFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuScalarMapperLegendFrame.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -173,6 +177,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMdiMaximizeWindowGuard.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMainWindowTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuComparisonViewMover.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractOverlayContentFrame.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractLegendFrame.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuCategoryLegendFrame.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuScalarMapperLegendFrame.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
@@ -223,6 +231,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuExpressionContextMenuManager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuCalculationsContextMenuManager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuDraggableOverlayFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractOverlayContentFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuAbstractLegendFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuCategoryLegendFrame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuScalarMapperLegendFrame.h
|
||||
)
|
||||
|
||||
list(APPEND QT_UI_FILES
|
||||
|
||||
177
ApplicationCode/UserInterface/RiuAbstractLegendFrame.cpp
Normal file
177
ApplicationCode/UserInterface/RiuAbstractLegendFrame.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiuAbstractLegendFrame.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuAbstractLegendFrame::RiuAbstractLegendFrame( QWidget* parent, const QString& title )
|
||||
: RiuAbstractOverlayContentFrame( parent )
|
||||
, m_title( title )
|
||||
{
|
||||
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QSize RiuAbstractLegendFrame::sizeHint() const
|
||||
{
|
||||
LayoutInfo layout( QSize( 200, 200 ) ); // Use default size
|
||||
layoutInfo( &layout );
|
||||
|
||||
QFontMetrics fontMetrics( this->font() );
|
||||
QStringList titleLines = m_title.split( "\n", QString::SkipEmptyParts );
|
||||
|
||||
int preferredContentHeight = titleLines.size() * layout.lineSpacing + labelCount() * layout.lineSpacing;
|
||||
int preferredHeight = preferredContentHeight + layout.margins.top() + layout.margins.bottom();
|
||||
|
||||
int maxTickTextWidth = 0;
|
||||
for ( int i = 0; i < labelCount(); ++i )
|
||||
{
|
||||
QString valueString = label( i );
|
||||
int textWidth = fontMetrics.boundingRect( valueString ).width();
|
||||
maxTickTextWidth = std::max( maxTickTextWidth, textWidth );
|
||||
}
|
||||
|
||||
int preferredWidth = layout.tickEndX + layout.margins.left() + layout.margins.right() + layout.tickTextLeadSpace +
|
||||
maxTickTextWidth;
|
||||
|
||||
preferredWidth = std::max( preferredWidth, fontMetrics.boundingRect( m_title ).width() );
|
||||
preferredWidth = std::min( preferredWidth, 400 );
|
||||
|
||||
return QSize( preferredWidth, preferredHeight );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QSize RiuAbstractLegendFrame::minimumSizeHint() const
|
||||
{
|
||||
LayoutInfo layout( QSize( 200, 200 ) ); // Use default size
|
||||
layoutInfo( &layout );
|
||||
|
||||
QFontMetrics fontMetrics( this->font() );
|
||||
QStringList titleLines = m_title.split( "\n", QString::SkipEmptyParts );
|
||||
|
||||
int preferredContentHeight = titleLines.size() * layout.lineSpacing + 2 * layout.lineSpacing;
|
||||
int preferredHeight = preferredContentHeight + layout.margins.top() + layout.margins.bottom();
|
||||
|
||||
int firstTextWidth = fontMetrics.boundingRect( label( 0 ) ).width();
|
||||
int lastTextWidth = fontMetrics.boundingRect( label( labelCount() - 1 ) ).width();
|
||||
int maxTickTextWidth = std::max( firstTextWidth, lastTextWidth );
|
||||
|
||||
int preferredWidth = layout.tickEndX + layout.margins.left() + layout.margins.right() + layout.tickTextLeadSpace +
|
||||
maxTickTextWidth;
|
||||
|
||||
preferredWidth = std::max( preferredWidth, fontMetrics.boundingRect( m_title ).width() );
|
||||
preferredWidth = std::min( preferredWidth, 400 );
|
||||
|
||||
return QSize( preferredWidth, preferredHeight );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuAbstractLegendFrame::renderTo( QPainter* painter, const QRect& targetRect )
|
||||
{
|
||||
LayoutInfo layout( QSize( targetRect.width(), targetRect.height() ) );
|
||||
layoutInfo( &layout );
|
||||
|
||||
painter->save();
|
||||
painter->translate( targetRect.topLeft() );
|
||||
QPoint titlePos( layout.margins.left(), layout.margins.top() + layout.lineSpacing / 2 );
|
||||
painter->drawText( titlePos, m_title );
|
||||
|
||||
QStringList titleLines = m_title.split( "\n", QString::SkipEmptyParts );
|
||||
|
||||
std::vector<std::pair<QPoint, QString>> visibleTickLabels = visibleLabels( layout );
|
||||
for ( auto tickLabel : visibleTickLabels )
|
||||
{
|
||||
painter->drawText( tickLabel.first, tickLabel.second );
|
||||
}
|
||||
|
||||
// Render color bar as one colored rectangle per color interval
|
||||
for ( int i = 0; i < rectCount(); ++i )
|
||||
{
|
||||
renderRect( painter, layout, i );
|
||||
}
|
||||
painter->drawRect( layout.colorBarRect );
|
||||
// painter->drawLine( QPointF( layout.tickMidX, layout.tickYPixelPos->get( i ) ),
|
||||
// QPointF( layout.tickMidX, layout.tickYPixelPos->get( i + 1 ) ) );
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuAbstractLegendFrame::paintEvent( QPaintEvent* e )
|
||||
{
|
||||
QPainter painter( this );
|
||||
renderTo( &painter, e->rect() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<QPoint, QString>> RiuAbstractLegendFrame::visibleLabels( const LayoutInfo& layout ) const
|
||||
{
|
||||
const int textX = layout.tickEndX + layout.tickTextLeadSpace;
|
||||
|
||||
const double overlapTolerance = 1.1 * layout.charHeight;
|
||||
int lastVisibleTextY = 0;
|
||||
|
||||
std::vector<std::pair<QPoint, QString>> visibleTickLabels;
|
||||
|
||||
int numLabels = labelCount();
|
||||
for ( int i = 0; i < numLabels; i++ )
|
||||
{
|
||||
int textY = labelPixelPosY( layout, i );
|
||||
|
||||
// Always draw first and last tick label. For all others, skip drawing if text ends up
|
||||
// on top of the previous label.
|
||||
if ( i != 0 && i != ( numLabels - 1 ) )
|
||||
{
|
||||
if ( std::fabs( static_cast<double>( textY - lastVisibleTextY ) ) < overlapTolerance )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Make sure it does not overlap the last tick as well
|
||||
|
||||
int lastTickY = layout.colorBarRect.bottom();
|
||||
|
||||
if ( std::fabs( static_cast<double>( lastTickY - textY ) ) < overlapTolerance )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
QString valueString = label( numLabels - i - 1 );
|
||||
QPoint pos( textX, textY );
|
||||
|
||||
lastVisibleTextY = textY;
|
||||
visibleTickLabels.push_back( {pos, valueString} );
|
||||
}
|
||||
return visibleTickLabels;
|
||||
}
|
||||
81
ApplicationCode/UserInterface/RiuAbstractLegendFrame.h
Normal file
81
ApplicationCode/UserInterface/RiuAbstractLegendFrame.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiuAbstractOverlayContentFrame.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QString>
|
||||
|
||||
class RiuAbstractLegendFrame : public RiuAbstractOverlayContentFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RiuAbstractLegendFrame( QWidget* parent, const QString& title );
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
void renderTo( QPainter* painter, const QRect& targetRect ) override;
|
||||
|
||||
protected:
|
||||
struct LayoutInfo
|
||||
{
|
||||
LayoutInfo( const QSize& size )
|
||||
{
|
||||
charHeight = 0;
|
||||
charAscent = 0;
|
||||
lineSpacing = 0;
|
||||
margins = QMargins( 0, 0, 0, 0 );
|
||||
tickEndX = 0;
|
||||
tickStartX = 0;
|
||||
tickMidX = 0;
|
||||
|
||||
overallLegendSize = size;
|
||||
}
|
||||
|
||||
int charHeight;
|
||||
int charAscent;
|
||||
int lineSpacing;
|
||||
QMargins margins;
|
||||
int tickStartX, tickMidX, tickEndX;
|
||||
int tickTextLeadSpace;
|
||||
|
||||
QRect colorBarRect;
|
||||
|
||||
std::vector<int> tickYPixelPos;
|
||||
|
||||
QSize overallLegendSize;
|
||||
};
|
||||
|
||||
void paintEvent( QPaintEvent* e ) override;
|
||||
std::vector<std::pair<QPoint, QString>> visibleLabels( const LayoutInfo& layout ) const;
|
||||
|
||||
private:
|
||||
virtual void layoutInfo( LayoutInfo* layout ) const = 0;
|
||||
virtual QString label( int index ) const = 0;
|
||||
virtual int labelPixelPosY( const LayoutInfo& layout, int index ) const = 0;
|
||||
virtual int labelCount() const = 0;
|
||||
virtual int rectCount() const = 0;
|
||||
|
||||
virtual void renderRect( QPainter* painter, const LayoutInfo& layout, int rectIndex ) const = 0;
|
||||
|
||||
protected:
|
||||
QString m_title;
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiuAbstractOverlayContentFrame.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QTextDocument>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuAbstractOverlayContentFrame::RiuAbstractOverlayContentFrame( QWidget* parent /*= nullptr */ )
|
||||
: QFrame( parent )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuAbstractOverlayContentFrame::~RiuAbstractOverlayContentFrame() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuTextOverlayContentFrame::RiuTextOverlayContentFrame( QWidget* parent /*= nullptr */ )
|
||||
: RiuAbstractOverlayContentFrame( parent )
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout( this );
|
||||
layout->setContentsMargins( 8, 8, 8, 8 );
|
||||
m_textLabel = new QLabel;
|
||||
layout->addWidget( m_textLabel );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuTextOverlayContentFrame::setText( const QString& text )
|
||||
{
|
||||
m_textLabel->setText( text );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuTextOverlayContentFrame::renderTo( QPainter* painter, const QRect& targetRect )
|
||||
{
|
||||
painter->save();
|
||||
painter->translate( targetRect.topLeft() + QPoint( this->contentsMargins().left(), this->contentsMargins().top() ) );
|
||||
painter->setFont( m_textLabel->font() );
|
||||
|
||||
QTextDocument td;
|
||||
td.setHtml( m_textLabel->text() );
|
||||
td.drawContents( painter );
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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>
|
||||
#include <QString>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class RiuAbstractOverlayContentFrame : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RiuAbstractOverlayContentFrame( QWidget* parent = nullptr );
|
||||
~RiuAbstractOverlayContentFrame();
|
||||
|
||||
virtual void renderTo( QPainter* painter, const QRect& targetRect ) = 0;
|
||||
};
|
||||
|
||||
class RiuTextOverlayContentFrame : public RiuAbstractOverlayContentFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RiuTextOverlayContentFrame( QWidget* parent = nullptr );
|
||||
|
||||
void setText( const QString& text );
|
||||
void renderTo( QPainter* painter, const QRect& targetRect ) override;
|
||||
|
||||
private:
|
||||
QPointer<QLabel> m_textLabel;
|
||||
};
|
||||
105
ApplicationCode/UserInterface/RiuCategoryLegendFrame.cpp
Normal file
105
ApplicationCode/UserInterface/RiuCategoryLegendFrame.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "RiuCategoryLegendFrame.h"
|
||||
|
||||
#include "cafCategoryLegend.h"
|
||||
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuCategoryLegendFrame::RiuCategoryLegendFrame( QWidget* parent, const QString& title, caf::CategoryMapper* categoryMapper )
|
||||
: RiuAbstractLegendFrame( parent, title )
|
||||
, m_categoryMapper( categoryMapper )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuCategoryLegendFrame::~RiuCategoryLegendFrame() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuCategoryLegendFrame::layoutInfo( LayoutInfo* layout ) const
|
||||
{
|
||||
QFontMetrics fontMetrics( this->font() );
|
||||
QStringList titleLines = m_title.split( "\n", QString::SkipEmptyParts );
|
||||
|
||||
layout->charHeight = fontMetrics.height();
|
||||
layout->charAscent = fontMetrics.ascent();
|
||||
layout->lineSpacing = ( fontMetrics.lineSpacing() * 3 ) / 2;
|
||||
layout->margins = QMargins( 8, 8, 8, 8 );
|
||||
layout->tickTextLeadSpace = 5;
|
||||
|
||||
int colorBarWidth = 25;
|
||||
int colorBarHeight = layout->overallLegendSize.height() - layout->margins.top() - layout->margins.bottom() -
|
||||
titleLines.size() * layout->lineSpacing;
|
||||
|
||||
int colorBarStartY = layout->margins.top() + titleLines.size() * layout->lineSpacing;
|
||||
|
||||
layout->colorBarRect = QRect( layout->margins.left(), colorBarStartY, colorBarWidth, colorBarHeight );
|
||||
|
||||
layout->tickStartX = layout->margins.left();
|
||||
layout->tickMidX = layout->margins.left() + layout->colorBarRect.width();
|
||||
layout->tickEndX = layout->tickMidX + 5;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiuCategoryLegendFrame::label( int index ) const
|
||||
{
|
||||
return cvfqt::Utils::toQString( m_categoryMapper->textForCategoryIndex( index ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuCategoryLegendFrame::labelCount() const
|
||||
{
|
||||
return (int)m_categoryMapper->categoryCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuCategoryLegendFrame::rectCount() const
|
||||
{
|
||||
return (int)m_categoryMapper->categoryCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuCategoryLegendFrame::renderRect( QPainter* painter, const LayoutInfo& layout, int index ) const
|
||||
{
|
||||
int categoryIndex = static_cast<int>( rectCount() - index - 1u );
|
||||
float categoryHeight = static_cast<float>( layout.colorBarRect.height() ) / labelCount();
|
||||
float pos = ( categoryIndex + 0.5 ) * categoryHeight / layout.colorBarRect.height();
|
||||
float domainValue = m_categoryMapper->domainValue( pos );
|
||||
cvf::Color3ub clr = m_categoryMapper->mapToColor( domainValue );
|
||||
// qDebug() << "Plot Legend: " << pos << " and " << domainValue << " = " << clr.r() << ", " << clr.g() << ", "
|
||||
// << clr.b();
|
||||
QColor color( clr.r(), clr.g(), clr.b() );
|
||||
|
||||
int yStart = layout.colorBarRect.top() + static_cast<int>( index * categoryHeight );
|
||||
int yEnd = layout.colorBarRect.top() + static_cast<int>( ( index + 1 ) * categoryHeight );
|
||||
|
||||
QRect rect( QPoint( layout.tickStartX, yStart ), QPoint( layout.tickMidX, yEnd ) );
|
||||
painter->fillRect( rect, QBrush( color ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuCategoryLegendFrame::labelPixelPosY( const LayoutInfo& layout, int index ) const
|
||||
{
|
||||
float categoryHeight = static_cast<float>( layout.colorBarRect.height() ) / labelCount();
|
||||
int textY = static_cast<int>( layout.colorBarRect.top() + index * categoryHeight + categoryHeight / 2 );
|
||||
textY += layout.charAscent / 2;
|
||||
return textY;
|
||||
}
|
||||
52
ApplicationCode/UserInterface/RiuCategoryLegendFrame.h
Normal file
52
ApplicationCode/UserInterface/RiuCategoryLegendFrame.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiuAbstractLegendFrame.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "cafCategoryMapper.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QSize>
|
||||
|
||||
class QFont;
|
||||
class QPaintEvent;
|
||||
class QPainter;
|
||||
class QRect;
|
||||
|
||||
class RiuCategoryLegendFrame : public RiuAbstractLegendFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RiuCategoryLegendFrame( QWidget* parent, const QString& title, caf::CategoryMapper* categoryMapper );
|
||||
~RiuCategoryLegendFrame();
|
||||
|
||||
private:
|
||||
void layoutInfo( LayoutInfo* layout ) const override;
|
||||
QString label( int index ) const override;
|
||||
int labelCount() const override;
|
||||
int rectCount() const override;
|
||||
void renderRect( QPainter* painter, const LayoutInfo& layout, int rectIndex ) const override;
|
||||
int labelPixelPosY( const LayoutInfo& layout, int index ) const override;
|
||||
|
||||
private:
|
||||
cvf::cref<caf::CategoryMapper> m_categoryMapper;
|
||||
};
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "RiaGuiApplication.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
#include "cafTitledOverlayFrame.h"
|
||||
#include "cafViewer.h"
|
||||
|
||||
@@ -30,23 +31,24 @@
|
||||
#include "cvfRendering.h"
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#include "glew/GL/glew.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget( QWidget* parent /*=0*/, QWidget* widgetToSnapTo )
|
||||
: RiuDraggableOverlayFrame( parent, widgetToSnapTo )
|
||||
RiuCvfOverlayItemWidget::RiuCvfOverlayItemWidget( caf::TitledOverlayFrame* overlayItem,
|
||||
QWidget* parent,
|
||||
const int snapMargins,
|
||||
const QColor& backgroundColor /*= QColor( 255, 255, 255, 100 ) */ )
|
||||
: RiuDraggableOverlayFrame( parent, snapMargins, backgroundColor )
|
||||
, m_overlayItem( overlayItem )
|
||||
{
|
||||
this->layout()->setMargin( 0 );
|
||||
this->layout()->setSpacing( 0 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -57,19 +59,25 @@ RiuCvfOverlayItemWidget::~RiuCvfOverlayItemWidget() {}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuCvfOverlayItemWidget::updateFromOverlayItem( caf::TitledOverlayFrame* item )
|
||||
QSize RiuCvfOverlayItemWidget::sizeHint() const
|
||||
{
|
||||
item->setRenderSize( item->preferredSize() );
|
||||
auto preferredSize = const_cast<caf::TitledOverlayFrame*>( m_overlayItem.p() )->preferredSize();
|
||||
return QSize( preferredSize.x(), preferredSize.y() );
|
||||
}
|
||||
|
||||
unsigned int width = item->renderSize().x();
|
||||
unsigned int height = item->renderSize().y();
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuCvfOverlayItemWidget::renderTo( QPainter* painter, const QRect& paintRect, double scaleX, double scaleY )
|
||||
{
|
||||
unsigned int width = static_cast<unsigned int>( paintRect.width() );
|
||||
unsigned int height = static_cast<unsigned int>( paintRect.height() );
|
||||
|
||||
m_overlayItem->setRenderSize( cvf::Vec2ui( width, height ) );
|
||||
|
||||
QGLFormat glFormat;
|
||||
glFormat.setDirectRendering( RiaGuiApplication::instance()->useShaders() );
|
||||
|
||||
// Enforce no border to avoid
|
||||
item->setBackgroundFrameColor( cvf::Color4f( 0, 0, 0, 0 ) );
|
||||
|
||||
caf::Viewer* viewer = new caf::Viewer( glFormat, nullptr );
|
||||
cvf::OpenGLContext* cvfOglContext = viewer->cvfOpenGLContext();
|
||||
viewer->resize( width, height );
|
||||
@@ -77,8 +85,8 @@ void RiuCvfOverlayItemWidget::updateFromOverlayItem( caf::TitledOverlayFrame* it
|
||||
// Create a rendering
|
||||
|
||||
cvf::ref<cvf::Rendering> rendering = new cvf::Rendering;
|
||||
item->setLayoutFixedPosition( {0, 0} );
|
||||
rendering->addOverlayItem( item );
|
||||
m_overlayItem->setLayoutFixedPosition( {0, 0} );
|
||||
rendering->addOverlayItem( m_overlayItem.p() );
|
||||
|
||||
rendering->camera()->setViewport( 0, 0, width, height );
|
||||
rendering->camera()->viewport()->setClearColor( {1, 1, 1, 0} );
|
||||
@@ -108,7 +116,7 @@ void RiuCvfOverlayItemWidget::updateFromOverlayItem( caf::TitledOverlayFrame* it
|
||||
|
||||
renderingSequence->render( cvfOglContext );
|
||||
|
||||
// Read data from framebuffer
|
||||
// Read data from frame buffer
|
||||
|
||||
cvf::UByteArray arr( 4 * width * height );
|
||||
glReadPixels( 0, 0, static_cast<GLsizei>( width ), static_cast<GLsizei>( height ), GL_RGBA, GL_UNSIGNED_BYTE, arr.ptr() );
|
||||
@@ -125,7 +133,17 @@ void RiuCvfOverlayItemWidget::updateFromOverlayItem( caf::TitledOverlayFrame* it
|
||||
|
||||
delete viewer;
|
||||
|
||||
m_overlayItemLabel->setPixmap( pixmap );
|
||||
this->setMinimumSize( QSize( width, height ) );
|
||||
this->resize( QSize( width, height ) );
|
||||
painter->save();
|
||||
painter->drawPixmap( paintRect.topLeft(), pixmap );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuCvfOverlayItemWidget::paintEvent( QPaintEvent* e )
|
||||
{
|
||||
QRect paintRect = e->rect();
|
||||
QPainter painter( this );
|
||||
renderTo( &painter, paintRect, 1.0, 1.0 );
|
||||
}
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QSize>
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
namespace caf
|
||||
{
|
||||
class TitledOverlayFrame;
|
||||
@@ -37,11 +40,18 @@ class RiuCvfOverlayItemWidget : public RiuDraggableOverlayFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RiuCvfOverlayItemWidget( QWidget* parent = nullptr, QWidget* widgetToSnapTo = nullptr );
|
||||
explicit RiuCvfOverlayItemWidget( caf::TitledOverlayFrame* overlayItem,
|
||||
QWidget* parent,
|
||||
const int snapMargins,
|
||||
const QColor& backgroundColor = QColor( 255, 255, 255, 100 ) );
|
||||
~RiuCvfOverlayItemWidget() override;
|
||||
|
||||
void updateFromOverlayItem( caf::TitledOverlayFrame* item );
|
||||
QSize sizeHint() const override;
|
||||
void renderTo( QPainter* painter, const QRect& paintRect, double scaleX, double scaleY );
|
||||
|
||||
// virtual QSize sizeHint() const override;
|
||||
// virtual QSize minimumSizeHint() const override;
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* e ) override;
|
||||
|
||||
private:
|
||||
cvf::ref<caf::TitledOverlayFrame> m_overlayItem;
|
||||
};
|
||||
|
||||
@@ -20,15 +20,18 @@
|
||||
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuDraggableOverlayFrame::RiuDraggableOverlayFrame( QWidget* parent, QWidget* widgetToSnapTo, const QColor& backgroundColor )
|
||||
RiuDraggableOverlayFrame::RiuDraggableOverlayFrame( QWidget* parent, const int snapMargins, const QColor& backgroundColor )
|
||||
: QFrame( parent )
|
||||
, m_anchorCorner( AnchorCorner::TopLeft )
|
||||
{
|
||||
RiuWidgetDragger* dragger = new RiuWidgetDragger( this, widgetToSnapTo );
|
||||
m_widgetDragger = new RiuWidgetDragger( this, snapMargins );
|
||||
|
||||
QPalette pal = this->palette();
|
||||
pal.setColor( QPalette::Window, backgroundColor );
|
||||
@@ -40,22 +43,84 @@ RiuDraggableOverlayFrame::RiuDraggableOverlayFrame( QWidget* parent, QWidget* wi
|
||||
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 );
|
||||
this->setContentsMargins( 1, 1, 1, 1 );
|
||||
m_layout = new QVBoxLayout( this );
|
||||
m_layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QLabel* RiuDraggableOverlayFrame::label()
|
||||
RiuAbstractOverlayContentFrame* RiuDraggableOverlayFrame::contentFrame()
|
||||
{
|
||||
return m_overlayItemLabel;
|
||||
return m_contentFrame;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuDraggableOverlayFrame::setContentFrame( RiuAbstractOverlayContentFrame* contentFrame )
|
||||
{
|
||||
if ( m_contentFrame )
|
||||
{
|
||||
m_layout->removeWidget( m_contentFrame );
|
||||
m_contentFrame->setParent( nullptr ); // TODO: check if both removeWidget and setParent is necessary
|
||||
delete m_contentFrame;
|
||||
m_contentFrame = nullptr;
|
||||
}
|
||||
|
||||
m_contentFrame = contentFrame;
|
||||
m_layout->addWidget( m_contentFrame );
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuDraggableOverlayFrame::renderTo( QPainter* painter, const QRect& targetRect )
|
||||
{
|
||||
if ( m_contentFrame )
|
||||
{
|
||||
painter->save();
|
||||
painter->fillRect( targetRect, this->palette().color( QWidget::backgroundRole() ) );
|
||||
QRect contentRect = targetRect;
|
||||
contentRect.adjust( -1, -1, -1, -1 );
|
||||
m_contentFrame->renderTo( painter, contentRect );
|
||||
painter->drawRect( targetRect );
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuDraggableOverlayFrame::setAnchorCorner( AnchorCorner corner )
|
||||
{
|
||||
m_anchorCorner = corner;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuDraggableOverlayFrame::AnchorCorner RiuDraggableOverlayFrame::anchorCorner() const
|
||||
{
|
||||
return m_anchorCorner;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QSize RiuDraggableOverlayFrame::sizeHint() const
|
||||
{
|
||||
QSize contentSize = m_contentFrame->sizeHint();
|
||||
return QSize( contentSize.width() + 2, contentSize.height() + 2 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QSize RiuDraggableOverlayFrame::minimumSizeHint() const
|
||||
{
|
||||
QSize contentSize = m_contentFrame->minimumSizeHint();
|
||||
return QSize( contentSize.width() + 2, contentSize.height() + 2 );
|
||||
}
|
||||
|
||||
@@ -17,21 +17,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiuAbstractOverlayContentFrame.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QPointer>
|
||||
|
||||
class QColor;
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
class RiuWidgetDragger;
|
||||
|
||||
class RiuDraggableOverlayFrame : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RiuDraggableOverlayFrame( QWidget* parent,
|
||||
QWidget* widgetToSnapTo = nullptr,
|
||||
const QColor& backgroundColor = QColor( 255, 255, 255, 100 ) );
|
||||
QLabel* label();
|
||||
enum class AnchorCorner
|
||||
{
|
||||
TopLeft,
|
||||
TopRight,
|
||||
};
|
||||
|
||||
protected:
|
||||
QPointer<QLabel> m_overlayItemLabel;
|
||||
public:
|
||||
RiuDraggableOverlayFrame( QWidget* parent,
|
||||
const int snapMargins,
|
||||
const QColor& backgroundColor = QColor( 255, 255, 255, 100 ) );
|
||||
|
||||
RiuAbstractOverlayContentFrame* contentFrame();
|
||||
void setContentFrame( RiuAbstractOverlayContentFrame* contentFrame );
|
||||
void renderTo( QPainter* painter, const QRect& targetRect );
|
||||
|
||||
void setAnchorCorner( AnchorCorner corner );
|
||||
AnchorCorner anchorCorner() const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
private:
|
||||
QPointer<RiuWidgetDragger> m_widgetDragger;
|
||||
QPointer<QVBoxLayout> m_layout;
|
||||
QPointer<RiuAbstractOverlayContentFrame> m_contentFrame;
|
||||
AnchorCorner m_anchorCorner;
|
||||
};
|
||||
|
||||
@@ -85,9 +85,7 @@ RiuGridCrossQwtPlot::RiuGridCrossQwtPlot( RimPlot* plotDefinition, QWidget* pare
|
||||
connect( m_zoomerRight, SIGNAL( zoomed( const QRectF& ) ), SLOT( onZoomedSlot() ) );
|
||||
connect( panner, SIGNAL( panned( int, int ) ), SLOT( onZoomedSlot() ) );
|
||||
|
||||
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>( new RiuPlotAnnotationTool() );
|
||||
m_infoBox = new RiuDraggableOverlayFrame( this, canvas() );
|
||||
|
||||
m_annotationTool = std::unique_ptr<RiuPlotAnnotationTool>( new RiuPlotAnnotationTool() );
|
||||
m_selectedPointMarker = new QwtPlotMarker;
|
||||
|
||||
// QwtPlotMarker takes ownership of the symbol, it is deleted in destructor of QwtPlotMarker
|
||||
@@ -121,112 +119,6 @@ RiuGridCrossQwtPlot::~RiuGridCrossQwtPlot()
|
||||
delete m_selectedPointMarker;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSet )
|
||||
{
|
||||
RiuCvfOverlayItemWidget* overlayWidget = nullptr;
|
||||
|
||||
auto it = m_legendWidgets.find( dataSet );
|
||||
if ( it == m_legendWidgets.end() || it->second == nullptr )
|
||||
{
|
||||
overlayWidget = new RiuCvfOverlayItemWidget( this, canvas() );
|
||||
m_legendWidgets[dataSet] = overlayWidget;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayWidget = it->second;
|
||||
}
|
||||
|
||||
if ( overlayWidget )
|
||||
{
|
||||
caf::TitledOverlayFrame* overlayItem = dataSet->legendConfig()->titledOverlayFrame();
|
||||
applyFontSizeToOverlayItem( overlayItem );
|
||||
resizeOverlayItemToFitPlot( overlayItem );
|
||||
overlayWidget->updateFromOverlayItem( overlayItem );
|
||||
}
|
||||
this->updateLegendLayout();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::removeDataSetLegend( RimGridCrossPlotDataSet* dataSetToShowLegendFor )
|
||||
{
|
||||
auto it = m_legendWidgets.find( dataSetToShowLegendFor );
|
||||
if ( it != m_legendWidgets.end() )
|
||||
{
|
||||
if ( it->second != nullptr )
|
||||
{
|
||||
it->second->hide();
|
||||
it->second->setParent( nullptr );
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
m_legendWidgets.erase( it );
|
||||
}
|
||||
|
||||
this->updateLegendLayout();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::removeDanglingDataSetLegends()
|
||||
{
|
||||
for ( auto it = m_legendWidgets.begin(); it != m_legendWidgets.end(); )
|
||||
{
|
||||
if ( it->first.isNull() )
|
||||
{
|
||||
if ( it->second != nullptr )
|
||||
{
|
||||
it->second->hide();
|
||||
it->second->setParent( nullptr );
|
||||
delete it->second;
|
||||
}
|
||||
m_legendWidgets.erase( it++ );
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::updateLegendSizesToMatchPlot()
|
||||
{
|
||||
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
|
||||
if ( !crossPlot ) return;
|
||||
|
||||
bool anyLegendResized = false;
|
||||
|
||||
for ( RimGridCrossPlotDataSet* dataSet : crossPlot->dataSets() )
|
||||
{
|
||||
if ( !dataSet->isChecked() || !dataSet->legendConfig()->showLegend() ) continue;
|
||||
|
||||
auto pairIt = m_legendWidgets.find( dataSet );
|
||||
if ( pairIt != m_legendWidgets.end() )
|
||||
{
|
||||
RiuCvfOverlayItemWidget* overlayWidget = pairIt->second;
|
||||
caf::TitledOverlayFrame* overlayItem = dataSet->legendConfig()->titledOverlayFrame();
|
||||
applyFontSizeToOverlayItem( overlayItem );
|
||||
if ( resizeOverlayItemToFitPlot( overlayItem ) )
|
||||
{
|
||||
anyLegendResized = true;
|
||||
overlayWidget->updateFromOverlayItem( overlayItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( anyLegendResized )
|
||||
{
|
||||
updateLegendLayout();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -265,11 +157,10 @@ void RiuGridCrossQwtPlot::setLegendFontSize( int fontSize )
|
||||
label->setFont( font );
|
||||
}
|
||||
}
|
||||
updateInfoBoxLayout();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The internal qwt legend is not used in grid plot windows
|
||||
/// The internal qwt legend is not used in multi plot windows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::setInternalQwtLegendVisible( bool visible )
|
||||
{
|
||||
@@ -283,169 +174,6 @@ void RiuGridCrossQwtPlot::setInternalQwtLegendVisible( bool visible )
|
||||
this->insertLegend( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::updateLayout()
|
||||
{
|
||||
QwtPlot::updateLayout();
|
||||
updateInfoBoxLayout();
|
||||
updateLegendLayout();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::updateInfoBoxLayout()
|
||||
{
|
||||
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
|
||||
if ( !crossPlot ) return;
|
||||
|
||||
bool showInfo = false;
|
||||
if ( crossPlot->showInfoBox() )
|
||||
{
|
||||
QStringList curveInfoTexts;
|
||||
for ( auto dataSet : crossPlot->dataSets() )
|
||||
{
|
||||
QString curveInfoText = dataSet->infoText();
|
||||
if ( dataSet->isChecked() && !curveInfoText.isEmpty() )
|
||||
{
|
||||
curveInfoTexts += curveInfoText;
|
||||
}
|
||||
}
|
||||
QStringList infoText;
|
||||
infoText << QString( "<b>View ID:</b> %1<br/>" ).arg( crossPlot->id() );
|
||||
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" ) );
|
||||
QFont font = m_infoBox->label()->font();
|
||||
font.setPointSize( crossPlot->legendFontSize() );
|
||||
m_infoBox->label()->setFont( font );
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::updateLegendLayout()
|
||||
{
|
||||
const int spacing = 5;
|
||||
int startMarginX = this->canvas()->pos().x() + spacing;
|
||||
int startMarginY = this->canvas()->pos().y() + spacing;
|
||||
|
||||
int xpos = startMarginX;
|
||||
int ypos = startMarginY;
|
||||
int maxColumnWidth = 0;
|
||||
|
||||
removeDanglingDataSetLegends();
|
||||
|
||||
RimGridCrossPlot* crossPlot = dynamic_cast<RimGridCrossPlot*>( plotDefinition() );
|
||||
|
||||
if ( !crossPlot ) return;
|
||||
|
||||
std::set<QString> legendTypes;
|
||||
|
||||
for ( RimGridCrossPlotDataSet* dataSet : crossPlot->dataSets() )
|
||||
{
|
||||
if ( dataSet->isChecked() && dataSet->groupingEnabled() && dataSet->legendConfig()->showLegend() )
|
||||
{
|
||||
auto pairIt = m_legendWidgets.find( dataSet );
|
||||
if ( pairIt != m_legendWidgets.end() )
|
||||
{
|
||||
RiuCvfOverlayItemWidget* overlayWidget = pairIt->second;
|
||||
|
||||
// Show only one copy of each legend type
|
||||
if ( !legendTypes.count( dataSet->groupParameter() ) )
|
||||
{
|
||||
if ( ypos + overlayWidget->height() + spacing > this->canvas()->height() )
|
||||
{
|
||||
xpos += spacing + maxColumnWidth;
|
||||
ypos = startMarginY;
|
||||
maxColumnWidth = 0;
|
||||
}
|
||||
|
||||
overlayWidget->show();
|
||||
overlayWidget->move( xpos, ypos );
|
||||
|
||||
ypos += pairIt->second->height() + spacing;
|
||||
maxColumnWidth = std::max( maxColumnWidth, pairIt->second->width() );
|
||||
legendTypes.insert( dataSet->groupParameter() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::resizeEvent( QResizeEvent* e )
|
||||
{
|
||||
QwtPlot::resizeEvent( e );
|
||||
updateLegendSizesToMatchPlot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiuGridCrossQwtPlot::resizeOverlayItemToFitPlot( caf::TitledOverlayFrame* overlayItem )
|
||||
{
|
||||
QSize plotSize = this->canvas()->contentsRect().size();
|
||||
cvf::Vec2ui existingRenderSize = overlayItem->renderSize();
|
||||
cvf::Vec2ui legendSize = overlayItem->preferredSize();
|
||||
|
||||
bool sizeAltered = false;
|
||||
|
||||
if ( plotSize.width() > 0 && (double)legendSize.x() > 0.9 * plotSize.width() )
|
||||
{
|
||||
legendSize.x() = ( plotSize.width() * 9 ) / 10;
|
||||
sizeAltered = true;
|
||||
}
|
||||
if ( plotSize.height() > 0 && (double)legendSize.y() > 0.9 * plotSize.height() )
|
||||
{
|
||||
legendSize.y() = ( plotSize.height() * 9 ) / 10;
|
||||
sizeAltered = true;
|
||||
}
|
||||
overlayItem->setRenderSize( legendSize );
|
||||
|
||||
if ( legendSize.x() != existingRenderSize.x() || legendSize.y() != existingRenderSize.y() )
|
||||
{
|
||||
sizeAltered = true;
|
||||
}
|
||||
|
||||
return sizeAltered;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -531,17 +259,6 @@ bool RiuGridCrossQwtPlot::curveText( const QwtPlotCurve* curve,
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuGridCrossQwtPlot::applyFontSizeToOverlayItem( caf::TitledOverlayFrame* overlayItem )
|
||||
{
|
||||
RimGridCrossPlot* crossPlot = static_cast<RimGridCrossPlot*>( ownerViewWindow() );
|
||||
int fontSize = crossPlot->legendFontSize();
|
||||
cvf::ref<cvf::Font> cafFont = RiaFontCache::getFont( RiaFontCache::fontSizeEnumFromPointSize( fontSize ) );
|
||||
overlayItem->setFont( cafFont.p() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -55,10 +55,6 @@ public:
|
||||
|
||||
RiuGridCrossQwtPlot( const RiuGridCrossQwtPlot& ) = delete;
|
||||
|
||||
void addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSetToShowLegendFor );
|
||||
void removeDataSetLegend( RimGridCrossPlotDataSet* dataSetToShowLegendFor );
|
||||
void removeDanglingDataSetLegends();
|
||||
void updateLegendSizesToMatchPlot();
|
||||
void updateAnnotationObjects( RimPlotAxisProperties* axisProperties );
|
||||
|
||||
RimViewWindow* ownerViewWindow() const override;
|
||||
@@ -67,17 +63,11 @@ public:
|
||||
void setInternalQwtLegendVisible( bool visible );
|
||||
|
||||
protected:
|
||||
void updateLayout() override;
|
||||
void updateInfoBoxLayout();
|
||||
void updateLegendLayout();
|
||||
void resizeEvent( QResizeEvent* e ) override;
|
||||
bool resizeOverlayItemToFitPlot( caf::TitledOverlayFrame* overlayItem );
|
||||
void contextMenuEvent( QContextMenuEvent* ) override;
|
||||
|
||||
void selectPoint( QwtPlotCurve* curve, int pointNumber ) override;
|
||||
void clearPointSelection() override;
|
||||
bool curveText( const QwtPlotCurve* curve, QString* curveTitle, QString* xParamName, QString* yParamName ) const;
|
||||
void applyFontSizeToOverlayItem( caf::TitledOverlayFrame* overlayItem );
|
||||
bool isZoomerActive() const override;
|
||||
void endZoomOperations() override;
|
||||
|
||||
@@ -85,12 +75,6 @@ private slots:
|
||||
void onZoomedSlot();
|
||||
|
||||
private:
|
||||
typedef caf::PdmPointer<RimGridCrossPlotDataSet> DataSetPtr;
|
||||
typedef QPointer<RiuCvfOverlayItemWidget> LegendPtr;
|
||||
typedef QPointer<RiuDraggableOverlayFrame> InfoBoxPtr;
|
||||
|
||||
InfoBoxPtr m_infoBox;
|
||||
std::map<DataSetPtr, LegendPtr> m_legendWidgets;
|
||||
std::unique_ptr<RiuPlotAnnotationTool> m_annotationTool;
|
||||
QwtPlotMarker* m_selectedPointMarker;
|
||||
|
||||
|
||||
@@ -680,7 +680,6 @@ void RiuMainWindow::createDockPanels()
|
||||
|
||||
m_projectTreeView = new caf::PdmUiTreeView( this );
|
||||
m_projectTreeView->enableSelectionManagerUpdating( true );
|
||||
m_styleSheet.applyToWidgetAndChildren( m_projectTreeView );
|
||||
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
m_projectTreeView->enableAppendOfClassNameToUiItemText( app->preferences()->appendClassNameToUiText() );
|
||||
|
||||
@@ -46,7 +46,6 @@ RiuMainWindowBase::RiuMainWindowBase()
|
||||
, m_blockSubWindowProjectTreeSelection( false )
|
||||
{
|
||||
setDockNestingEnabled( true );
|
||||
m_styleSheet = createStyleSheet();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -94,7 +94,6 @@ protected slots:
|
||||
|
||||
protected:
|
||||
caf::PdmUiTreeView* m_projectTreeView;
|
||||
caf::UiStyleSheet m_styleSheet;
|
||||
bool m_allowActiveViewChangeFromSelection; // To be used in selectedObjectsChanged() to control
|
||||
// whether to select the corresponding active view or not
|
||||
private:
|
||||
|
||||
@@ -42,10 +42,12 @@
|
||||
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_plot_layout.h"
|
||||
#include "qwt_plot_renderer.h"
|
||||
#include "qwt_scale_draw.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFocusEvent>
|
||||
#include <QFontMetrics>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QMenu>
|
||||
@@ -279,6 +281,14 @@ void RiuMultiPlotWindow::scheduleReplotOfAllPlots()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuMultiPlotWindow::renderTo( QPainter* painter )
|
||||
{
|
||||
doRenderTo( painter );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -437,7 +447,7 @@ void RiuMultiPlotWindow::dropEvent( QDropEvent* event )
|
||||
|
||||
if ( insertAfter != plotToMove )
|
||||
{
|
||||
m_plotDefinition->movePlotsToThis( { plotToMove }, insertAfter );
|
||||
m_plotDefinition->movePlotsToThis( {plotToMove}, insertAfter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -534,13 +544,22 @@ void RiuMultiPlotWindow::reinsertPlotWidgets()
|
||||
|
||||
for ( int tIdx = 0; tIdx < m_plotWidgets.size(); ++tIdx )
|
||||
{
|
||||
m_plotWidgets[tIdx]->hide();
|
||||
m_legends[tIdx]->hide();
|
||||
m_subTitles[tIdx]->hide();
|
||||
if ( m_plotWidgets[tIdx] )
|
||||
{
|
||||
m_plotWidgets[tIdx]->hide();
|
||||
}
|
||||
if ( m_legends[tIdx] )
|
||||
{
|
||||
m_legends[tIdx]->hide();
|
||||
}
|
||||
if ( m_subTitles[tIdx] )
|
||||
{
|
||||
m_subTitles[tIdx]->hide();
|
||||
}
|
||||
}
|
||||
|
||||
QList<QPointer<QLabel>> subTitles = this->visibleTitles();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = this->visibleLegends();
|
||||
QList<QPointer<QLabel>> subTitles = this->subTitlesForVisiblePlots();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
|
||||
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
|
||||
|
||||
if ( plotWidgets.empty() && acceptDrops() )
|
||||
@@ -566,7 +585,8 @@ void RiuMultiPlotWindow::reinsertPlotWidgets()
|
||||
std::tie( row, column ) = findAvailableRowAndColumn( row, column, colSpan, rowAndColumnCount.second );
|
||||
|
||||
m_gridLayout->addWidget( subTitles[visibleIndex], 3 * row, column, 1, colSpan );
|
||||
m_gridLayout->addWidget( legends[visibleIndex], 3 * row + 1, column, 1, colSpan );
|
||||
m_gridLayout
|
||||
->addWidget( legends[visibleIndex], 3 * row + 1, column, 1, colSpan, Qt::AlignHCenter | Qt::AlignBottom );
|
||||
m_gridLayout->addWidget( plotWidgets[visibleIndex], 3 * row + 2, column, 1 + ( rowSpan - 1 ) * 3, colSpan );
|
||||
|
||||
subTitles[visibleIndex]->setVisible( m_plotDefinition->showPlotTitles() );
|
||||
@@ -617,7 +637,7 @@ int RiuMultiPlotWindow::alignCanvasTops()
|
||||
CVF_ASSERT( m_legends.size() == m_plotWidgets.size() );
|
||||
|
||||
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = visiblePlotWidgets();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = visibleLegends();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = legendsForVisiblePlots();
|
||||
if ( plotWidgets.empty() ) return 0;
|
||||
|
||||
auto rowAndColumnCount = this->rowAndColumnCount( plotWidgets.size() );
|
||||
@@ -701,7 +721,7 @@ QList<QPointer<RiuQwtPlotWidget>> RiuMultiPlotWindow::visiblePlotWidgets() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<QPointer<RiuQwtPlotLegend>> RiuMultiPlotWindow::visibleLegends() const
|
||||
QList<QPointer<RiuQwtPlotLegend>> RiuMultiPlotWindow::legendsForVisiblePlots() const
|
||||
{
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends;
|
||||
for ( int i = 0; i < m_plotWidgets.size(); ++i )
|
||||
@@ -717,7 +737,7 @@ QList<QPointer<RiuQwtPlotLegend>> RiuMultiPlotWindow::visibleLegends() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<QPointer<QLabel>> RiuMultiPlotWindow::visibleTitles() const
|
||||
QList<QPointer<QLabel>> RiuMultiPlotWindow::subTitlesForVisiblePlots() const
|
||||
{
|
||||
QList<QPointer<QLabel>> subTitles;
|
||||
for ( int i = 0; i < m_plotWidgets.size(); ++i )
|
||||
@@ -765,3 +785,37 @@ std::pair<int, int>
|
||||
}
|
||||
return std::make_pair( availableRow, availableColumn );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuMultiPlotWindow::doRenderTo( QPainter* painter )
|
||||
{
|
||||
setSelectionsVisible( false );
|
||||
m_plotTitle->render( painter );
|
||||
|
||||
for ( auto subTitle : subTitlesForVisiblePlots() )
|
||||
{
|
||||
if ( subTitle->isVisible() )
|
||||
{
|
||||
subTitle->render( painter, m_plotWidgetFrame->mapToParent( subTitle->frameGeometry().topLeft() ) );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto legend : legendsForVisiblePlots() )
|
||||
{
|
||||
legend->render( painter, m_plotWidgetFrame->mapToParent( legend->frameGeometry().topLeft() ) );
|
||||
}
|
||||
|
||||
for ( auto plotWidget : visiblePlotWidgets() )
|
||||
{
|
||||
QRect plotWidgetGeometry = plotWidget->frameGeometry();
|
||||
QPoint plotWidgetTopLeft = plotWidgetGeometry.topLeft();
|
||||
QPoint plotWidgetFrameTopLeft = m_plotWidgetFrame->frameGeometry().topLeft();
|
||||
plotWidgetGeometry.moveTo( plotWidgetTopLeft + plotWidgetFrameTopLeft );
|
||||
|
||||
plotWidget->renderTo( painter, plotWidgetGeometry );
|
||||
}
|
||||
|
||||
setSelectionsVisible( true );
|
||||
}
|
||||
|
||||
@@ -41,8 +41,11 @@ class RiuQwtPlotWidget;
|
||||
|
||||
class QFocusEvent;
|
||||
class QLabel;
|
||||
class QPainter;
|
||||
class QScrollBar;
|
||||
class QwtLegend;
|
||||
class QwtLegendData;
|
||||
class QwtPlot;
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
@@ -78,6 +81,8 @@ public:
|
||||
void scheduleReplotOfAllPlots();
|
||||
virtual void updateVerticalScrollBar( double visibleMin, double visibleMax, double totalMin, double totalMax ) {}
|
||||
|
||||
void renderTo( QPainter* painter );
|
||||
|
||||
protected:
|
||||
void contextMenuEvent( QContextMenuEvent* ) override;
|
||||
QLabel* createTitleLabel() const;
|
||||
@@ -104,11 +109,13 @@ protected:
|
||||
caf::UiStyleSheet createDropTargetStyleSheet();
|
||||
|
||||
QList<QPointer<RiuQwtPlotWidget>> visiblePlotWidgets() const;
|
||||
QList<QPointer<RiuQwtPlotLegend>> visibleLegends() const;
|
||||
QList<QPointer<QLabel>> visibleTitles() const;
|
||||
QList<QPointer<RiuQwtPlotLegend>> legendsForVisiblePlots() const;
|
||||
QList<QPointer<QLabel>> subTitlesForVisiblePlots() const;
|
||||
|
||||
std::pair<int, int> findAvailableRowAndColumn( int startRow, int startColumn, int columnSpan, int columnCount ) const;
|
||||
|
||||
virtual void doRenderTo( QPainter* painter );
|
||||
|
||||
private slots:
|
||||
virtual void performUpdate();
|
||||
void onLegendUpdated();
|
||||
|
||||
@@ -31,6 +31,11 @@ RiuQwtPlotLegend::RiuQwtPlotLegend( QWidget* parent /*= nullptr */ )
|
||||
: QwtLegend( parent )
|
||||
, m_columnCount( 1 )
|
||||
{
|
||||
QwtDynGridLayout* legendLayout = qobject_cast<QwtDynGridLayout*>( contentsWidget()->layout() );
|
||||
if ( legendLayout )
|
||||
{
|
||||
legendLayout->setExpandingDirections( Qt::Horizontal | Qt::Vertical );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -75,7 +80,7 @@ QSize RiuQwtPlotLegend::sizeHint() const
|
||||
maxHeight = std::max( maxHeight, itemSize.height() );
|
||||
}
|
||||
QMargins margins = legendLayout->contentsMargins();
|
||||
int totalSpacing = ( numRows + 1 ) * legendLayout->spacing() + margins.top() + margins.bottom();
|
||||
int totalSpacing = ( numRows + 2 ) * legendLayout->spacing() + margins.top() + margins.bottom();
|
||||
|
||||
int height = maxHeight * numRows + totalSpacing;
|
||||
|
||||
|
||||
@@ -119,8 +119,6 @@ void RiuQwtPlotTools::setDefaultAxes( QwtPlot* plot )
|
||||
plot->enableAxis( QwtPlot::xTop, false );
|
||||
plot->enableAxis( QwtPlot::yRight, false );
|
||||
|
||||
plot->axisScaleDraw( QwtPlot::xBottom )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
|
||||
plot->axisScaleDraw( QwtPlot::yLeft )->enableComponent( QwtAbstractScaleDraw::Backbone, false );
|
||||
plot->axisWidget( QwtPlot::xBottom )->setMargin( 0 );
|
||||
plot->axisWidget( QwtPlot::yLeft )->setMargin( 0 );
|
||||
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaFontCache.h"
|
||||
#include "RiaPlotWindowRedrawScheduler.h"
|
||||
|
||||
#include "RimPlot.h"
|
||||
#include "RimPlotCurve.h"
|
||||
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtCurvePointTracker.h"
|
||||
#include "RiuQwtLinearScaleEngine.h"
|
||||
@@ -35,16 +37,19 @@
|
||||
#include "cafAssert.h"
|
||||
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_plot_canvas.h"
|
||||
#include "qwt_plot_curve.h"
|
||||
#include "qwt_plot_grid.h"
|
||||
#include "qwt_plot_layout.h"
|
||||
#include "qwt_plot_marker.h"
|
||||
#include "qwt_plot_picker.h"
|
||||
#include "qwt_plot_renderer.h"
|
||||
#include "qwt_scale_draw.h"
|
||||
#include "qwt_scale_widget.h"
|
||||
#include "qwt_symbol.h"
|
||||
#include "qwt_text.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDrag>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
@@ -55,6 +60,7 @@
|
||||
#include <QScrollArea>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cfloat>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -64,6 +70,7 @@ RiuQwtPlotWidget::RiuQwtPlotWidget( RimPlot* plot, QWidget* parent )
|
||||
: QwtPlot( parent )
|
||||
, m_plotDefinition( plot )
|
||||
, m_draggable( true )
|
||||
, m_overlayMargins( 5 )
|
||||
{
|
||||
RiuQwtPlotTools::setCommonPlotBehaviour( this );
|
||||
|
||||
@@ -404,11 +411,11 @@ void RiuQwtPlotWidget::setWidgetState( const QString& widgetState )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Adds an overlay frame. The overlay frame becomes the responsibility of the plot widget
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::addOverlayFrame( QFrame* overlayFrame )
|
||||
void RiuQwtPlotWidget::addOverlayFrame( RiuDraggableOverlayFrame* overlayFrame )
|
||||
{
|
||||
if ( std::find( m_overlayFrames.begin(), m_overlayFrames.end(), overlayFrame ) == m_overlayFrames.end() )
|
||||
{
|
||||
overlayFrame->setParent( this );
|
||||
overlayFrame->setParent( this->canvas() );
|
||||
m_overlayFrames.push_back( overlayFrame );
|
||||
updateLayout();
|
||||
}
|
||||
@@ -417,7 +424,7 @@ void RiuQwtPlotWidget::addOverlayFrame( QFrame* overlayFrame )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Remove the overlay widget. The frame becomes the responsibility of the caller
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::removeOverlayFrame( QFrame* overlayFrame )
|
||||
void RiuQwtPlotWidget::removeOverlayFrame( RiuDraggableOverlayFrame* overlayFrame )
|
||||
{
|
||||
overlayFrame->hide();
|
||||
overlayFrame->setParent( nullptr );
|
||||
@@ -544,6 +551,16 @@ void RiuQwtPlotWidget::showEvent( QShowEvent* event )
|
||||
QwtPlot::showEvent( event );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::resizeEvent( QResizeEvent* event )
|
||||
{
|
||||
QwtPlot::resizeEvent( event );
|
||||
updateOverlayFrameLayout();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -587,6 +604,47 @@ bool RiuQwtPlotWidget::isZoomerActive() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::endZoomOperations() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::renderTo( QPainter* painter, const QRect& targetRect )
|
||||
{
|
||||
static_cast<QwtPlotCanvas*>( this->canvas() )->setPaintAttribute( QwtPlotCanvas::BackingStore, false );
|
||||
QwtPlotRenderer renderer( this );
|
||||
renderer.render( this, painter, targetRect );
|
||||
static_cast<QwtPlotCanvas*>( this->canvas() )->setPaintAttribute( QwtPlotCanvas::BackingStore, true );
|
||||
|
||||
for ( RiuDraggableOverlayFrame* overlayFrame : m_overlayFrames )
|
||||
{
|
||||
if ( overlayFrame->isVisible() )
|
||||
{
|
||||
QPoint overlayTopLeftInCanvasCoords = overlayFrame->frameGeometry().topLeft();
|
||||
QPoint canvasTopLeftInPlotCoords = this->canvas()->frameGeometry().topLeft();
|
||||
QPoint plotTopLeftInWindowCoords = targetRect.topLeft();
|
||||
|
||||
QPoint overlayTopLeftInWindowCoords = plotTopLeftInWindowCoords + canvasTopLeftInPlotCoords +
|
||||
overlayTopLeftInCanvasCoords;
|
||||
{
|
||||
QRect overlayRect = overlayFrame->frameGeometry();
|
||||
QSize desiredSize = overlayRect.size();
|
||||
QSize minimumSize = overlayFrame->minimumSizeHint();
|
||||
QSize actualSize = desiredSize.expandedTo( minimumSize );
|
||||
overlayRect.moveTo( overlayTopLeftInWindowCoords );
|
||||
overlayRect.setSize( actualSize );
|
||||
overlayFrame->renderTo( painter, overlayRect );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuQwtPlotWidget::overlayMargins() const
|
||||
{
|
||||
return m_overlayMargins;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -651,26 +709,47 @@ caf::UiStyleSheet RiuQwtPlotWidget::createCanvasStyleSheet() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotWidget::updateOverlayFrameLayout()
|
||||
{
|
||||
const int spacing = 5;
|
||||
int startMarginX = this->canvas()->pos().x() + spacing;
|
||||
int startMarginY = this->canvas()->pos().y() + spacing;
|
||||
const int spacing = 5;
|
||||
|
||||
int xpos = startMarginX;
|
||||
int ypos = startMarginY;
|
||||
int maxColumnWidth = 0;
|
||||
for ( QPointer<QFrame> frame : m_overlayFrames )
|
||||
int xpos = spacing;
|
||||
int ypos = spacing;
|
||||
int widthOfCurrentColumn = 0;
|
||||
|
||||
QSize canvasSize = this->canvas()->size();
|
||||
QSize maxFrameSize( canvasSize.width() - 2 * m_overlayMargins, canvasSize.height() - 2 * m_overlayMargins );
|
||||
|
||||
for ( RiuDraggableOverlayFrame* frame : m_overlayFrames )
|
||||
{
|
||||
if ( !frame.isNull() )
|
||||
if ( frame )
|
||||
{
|
||||
if ( ypos + frame->height() + spacing > this->canvas()->height() )
|
||||
QSize minFrameSize = frame->minimumSizeHint();
|
||||
QSize desiredFrameSize = frame->sizeHint();
|
||||
|
||||
int width = std::min( std::max( minFrameSize.width(), desiredFrameSize.width() ), maxFrameSize.width() );
|
||||
int height = std::min( std::max( minFrameSize.height(), desiredFrameSize.height() ), maxFrameSize.height() );
|
||||
|
||||
frame->resize( width, height );
|
||||
|
||||
if ( frame->anchorCorner() == RiuDraggableOverlayFrame::AnchorCorner::TopLeft )
|
||||
{
|
||||
xpos += spacing + maxColumnWidth;
|
||||
ypos = startMarginY;
|
||||
maxColumnWidth = 0;
|
||||
if ( ypos + frame->height() + spacing > this->canvas()->height() && widthOfCurrentColumn > 0 )
|
||||
{
|
||||
xpos += spacing + widthOfCurrentColumn;
|
||||
ypos = spacing;
|
||||
widthOfCurrentColumn = 0;
|
||||
}
|
||||
frame->move( xpos, ypos );
|
||||
ypos += frame->height() + spacing;
|
||||
widthOfCurrentColumn = std::max( widthOfCurrentColumn, frame->width() );
|
||||
}
|
||||
else if ( frame->anchorCorner() == RiuDraggableOverlayFrame::AnchorCorner::TopRight )
|
||||
{
|
||||
QRect frameRect = frame->frameGeometry();
|
||||
QRect canvasRect = canvas()->rect();
|
||||
QPoint canvasTopRight = canvasRect.topRight();
|
||||
frameRect.moveTopRight( QPoint( canvasTopRight.x() - spacing, canvasTopRight.y() + spacing ) );
|
||||
frame->move( frameRect.topLeft() );
|
||||
}
|
||||
frame->move( xpos, ypos );
|
||||
ypos += frame->height() + spacing;
|
||||
maxColumnWidth = std::max( maxColumnWidth, frame->width() );
|
||||
frame->show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
class RiaPlotWindowRedrawScheduler;
|
||||
class RimPlot;
|
||||
class RiuDraggableOverlayFrame;
|
||||
|
||||
class QwtLegend;
|
||||
class QwtPicker;
|
||||
@@ -98,16 +99,20 @@ public:
|
||||
void scheduleReplot();
|
||||
void setWidgetState( const QString& widgetState );
|
||||
|
||||
void addOverlayFrame( QFrame* overlayWidget );
|
||||
void removeOverlayFrame( QFrame* overlayWidget );
|
||||
void addOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
|
||||
void removeOverlayFrame( RiuDraggableOverlayFrame* overlayWidget );
|
||||
void updateLayout() override;
|
||||
|
||||
void renderTo( QPainter* painter, const QRect& targetRect );
|
||||
int overlayMargins() const;
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
bool eventFilter( QObject* watched, QEvent* event ) override;
|
||||
void hideEvent( QHideEvent* event ) override;
|
||||
void showEvent( QShowEvent* event ) override;
|
||||
void resizeEvent( QResizeEvent* event ) override;
|
||||
|
||||
void applyAxisTitleToQwt( QwtPlot::Axis axis );
|
||||
|
||||
@@ -138,8 +143,9 @@ private:
|
||||
std::map<QwtPlot::Axis, bool> m_axisTitlesEnabled;
|
||||
QPointer<QwtPlotPicker> m_plotPicker;
|
||||
bool m_draggable;
|
||||
const int m_overlayMargins;
|
||||
|
||||
QList<QPointer<QFrame>> m_overlayFrames;
|
||||
QList<QPointer<RiuDraggableOverlayFrame>> m_overlayFrames;
|
||||
|
||||
struct CurveColors
|
||||
{
|
||||
|
||||
203
ApplicationCode/UserInterface/RiuScalarMapperLegendFrame.cpp
Normal file
203
ApplicationCode/UserInterface/RiuScalarMapperLegendFrame.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiuScalarMapperLegendFrame.h"
|
||||
|
||||
#include "cvfString.h"
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuScalarMapperLegendFrame::RiuScalarMapperLegendFrame( QWidget* parent,
|
||||
const QString& title,
|
||||
cvf::ScalarMapper* scalarMapper )
|
||||
: RiuAbstractLegendFrame( parent, title )
|
||||
, m_scalarMapper( scalarMapper )
|
||||
, m_tickNumberPrecision( 4 )
|
||||
, m_numberFormat( RimRegularLegendConfig::AUTO )
|
||||
{
|
||||
if ( m_scalarMapper.notNull() )
|
||||
{
|
||||
m_scalarMapper->majorTickValues( &m_tickValues );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuScalarMapperLegendFrame::~RiuScalarMapperLegendFrame() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuScalarMapperLegendFrame::setTickPrecision( int precision )
|
||||
{
|
||||
m_tickNumberPrecision = precision;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuScalarMapperLegendFrame::setTickFormat( NumberFormat format )
|
||||
{
|
||||
m_numberFormat = format;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuScalarMapperLegendFrame::layoutInfo( LayoutInfo* layout ) const
|
||||
{
|
||||
QFontMetrics fontMetrics( this->font() );
|
||||
QStringList titleLines = m_title.split( "\n", QString::SkipEmptyParts );
|
||||
|
||||
layout->charHeight = fontMetrics.height();
|
||||
layout->charAscent = fontMetrics.ascent();
|
||||
layout->lineSpacing = ( fontMetrics.lineSpacing() * 3 ) / 2;
|
||||
layout->margins = QMargins( 8, 8, 8, 8 );
|
||||
layout->tickTextLeadSpace = 5;
|
||||
|
||||
int colorBarWidth = 25;
|
||||
int colorBarHeight = layout->overallLegendSize.height() - layout->margins.top() - layout->margins.bottom() -
|
||||
titleLines.size() * layout->lineSpacing;
|
||||
|
||||
int colorBarStartY = layout->margins.top() + titleLines.size() * layout->lineSpacing;
|
||||
|
||||
layout->colorBarRect = QRect( layout->margins.left(), colorBarStartY, colorBarWidth, colorBarHeight );
|
||||
|
||||
layout->tickStartX = layout->margins.left();
|
||||
layout->tickMidX = layout->margins.left() + layout->colorBarRect.width();
|
||||
layout->tickEndX = layout->tickMidX + 5;
|
||||
|
||||
// Build array containing the pixel positions of all the ticks
|
||||
int numTicks = (int)m_tickValues.size();
|
||||
layout->tickYPixelPos.reserve( numTicks );
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < numTicks; i++ )
|
||||
{
|
||||
double t = 0.0;
|
||||
if ( m_scalarMapper.notNull() )
|
||||
{
|
||||
t = cvf::Math::clamp( m_scalarMapper->normalizedValue( m_tickValues[i] ), 0.0, 1.1 );
|
||||
}
|
||||
|
||||
if ( i == 0 )
|
||||
{
|
||||
layout->tickYPixelPos.push_back( 0.0 );
|
||||
}
|
||||
else if ( i == numTicks - 1 )
|
||||
{
|
||||
layout->tickYPixelPos.push_back( layout->colorBarRect.height() );
|
||||
}
|
||||
else
|
||||
{
|
||||
layout->tickYPixelPos.push_back( t * layout->colorBarRect.height() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiuScalarMapperLegendFrame::label( int index ) const
|
||||
{
|
||||
double tickValue = m_tickValues[index];
|
||||
QString valueString;
|
||||
switch ( m_numberFormat )
|
||||
{
|
||||
case RimRegularLegendConfig::FIXED:
|
||||
valueString = QString::number( tickValue, 'f', m_tickNumberPrecision );
|
||||
break;
|
||||
case RimRegularLegendConfig::SCIENTIFIC:
|
||||
valueString = QString::number( tickValue, 'e', m_tickNumberPrecision );
|
||||
break;
|
||||
default:
|
||||
valueString = QString::number( tickValue );
|
||||
break;
|
||||
}
|
||||
return valueString;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuScalarMapperLegendFrame::labelCount() const
|
||||
{
|
||||
return (int)m_tickValues.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuScalarMapperLegendFrame::rectCount() const
|
||||
{
|
||||
return (int)m_tickValues.size() - 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuScalarMapperLegendFrame::renderRect( QPainter* painter, const LayoutInfo& layout, int rectIndex ) const
|
||||
{
|
||||
int rectIndexFromBottom = rectCount() - rectIndex - 1;
|
||||
cvf::Color3ub startColor = m_scalarMapper->mapToColor(
|
||||
m_scalarMapper->domainValue( m_tickValues[rectIndexFromBottom] ) );
|
||||
cvf::Color3ub endColor = m_scalarMapper->mapToColor(
|
||||
m_scalarMapper->domainValue( m_tickValues[rectIndexFromBottom + 1] ) );
|
||||
QColor startQColor( startColor.r(), startColor.g(), startColor.b() );
|
||||
QColor endQColor( endColor.r(), endColor.g(), endColor.b() );
|
||||
|
||||
QRectF gradientRect( QPointF( layout.tickStartX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom] + 1 ),
|
||||
QPointF( layout.tickStartX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom + 1] + 1 ) );
|
||||
|
||||
QLinearGradient gradient( gradientRect.topLeft(), gradientRect.bottomRight() );
|
||||
gradient.setCoordinateMode( QGradient::LogicalMode );
|
||||
gradient.setColorAt( 0.0, startQColor );
|
||||
gradient.setColorAt( 1.0, endQColor );
|
||||
|
||||
QRectF rect( QPointF( layout.tickStartX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom] + 1 ),
|
||||
QPointF( layout.tickMidX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom + 1] + 1 ) );
|
||||
|
||||
painter->fillRect( rect, QBrush( gradient ) );
|
||||
painter->drawLine( QPointF( layout.tickStartX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom] + 1 ),
|
||||
QPointF( layout.tickEndX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom] + 1 ) );
|
||||
painter->drawLine( QPointF( layout.tickStartX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom + 1] + 1 ),
|
||||
QPointF( layout.tickEndX,
|
||||
layout.colorBarRect.bottom() - layout.tickYPixelPos[rectIndexFromBottom + 1] + 1 ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RiuScalarMapperLegendFrame::labelPixelPosY( const LayoutInfo& layout, int index ) const
|
||||
{
|
||||
int indexFromBottom = labelCount() - index - 1;
|
||||
return layout.colorBarRect.bottom() - layout.tickYPixelPos[indexFromBottom] + layout.charAscent / 2;
|
||||
}
|
||||
62
ApplicationCode/UserInterface/RiuScalarMapperLegendFrame.h
Normal file
62
ApplicationCode/UserInterface/RiuScalarMapperLegendFrame.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimRegularLegendConfig.h"
|
||||
#include "RiuAbstractLegendFrame.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
#include "cvfRect.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QSize>
|
||||
|
||||
class QFont;
|
||||
class QPaintEvent;
|
||||
class QPainter;
|
||||
class QRect;
|
||||
|
||||
class RiuScalarMapperLegendFrame : public RiuAbstractLegendFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using NumberFormat = RimRegularLegendConfig::NumberFormatType;
|
||||
|
||||
public:
|
||||
RiuScalarMapperLegendFrame( QWidget* parent, const QString& title, cvf::ScalarMapper* scalarMapper );
|
||||
~RiuScalarMapperLegendFrame();
|
||||
|
||||
void setTickPrecision( int precision );
|
||||
void setTickFormat( NumberFormat format );
|
||||
|
||||
private:
|
||||
void layoutInfo( LayoutInfo* layout ) const override;
|
||||
QString label( int index ) const override;
|
||||
int labelCount() const override;
|
||||
int rectCount() const override;
|
||||
void renderRect( QPainter* painter, const LayoutInfo& layout, int rectIndex ) const override;
|
||||
int labelPixelPosY( const LayoutInfo& layout, int index ) const override;
|
||||
|
||||
private:
|
||||
cvf::cref<cvf::ScalarMapper> m_scalarMapper;
|
||||
std::vector<double> m_tickValues;
|
||||
int m_tickNumberPrecision;
|
||||
NumberFormat m_numberFormat;
|
||||
};
|
||||
@@ -27,14 +27,6 @@ RiuWellLogPlot::RiuWellLogPlot( RimWellLogPlot* plotDefinition, QWidget* parent
|
||||
connect( m_trackScrollBar, SIGNAL( valueChanged( int ) ), this, SLOT( slotSetMinDepth( int ) ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiuWellLogPlot::isScrollbarVisible() const
|
||||
{
|
||||
return m_trackScrollBar->isVisible();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -48,9 +40,11 @@ RimWellLogPlot* RiuWellLogPlot::wellLogPlotDefinition()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuWellLogPlot::setScrollbarVisible( bool visible )
|
||||
void RiuWellLogPlot::doRenderTo( QPainter* painter )
|
||||
{
|
||||
m_trackScrollBar->setVisible( visible );
|
||||
m_trackScrollBar->setVisible( false );
|
||||
RiuMultiPlotWindow::doRenderTo( painter );
|
||||
m_trackScrollBar->setVisible( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -102,7 +96,7 @@ bool RiuWellLogPlot::showYAxis( int row, int column ) const
|
||||
void RiuWellLogPlot::reinsertScrollbar()
|
||||
{
|
||||
QList<QPointer<RiuQwtPlotWidget>> plotWidgets = this->visiblePlotWidgets();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = this->visibleLegends();
|
||||
QList<QPointer<RiuQwtPlotLegend>> legends = this->legendsForVisiblePlots();
|
||||
int rowCount = this->m_gridLayout->rowCount();
|
||||
int colCount = this->m_gridLayout->columnCount();
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ class RiuWellLogPlot : public RiuMultiPlotWindow
|
||||
public:
|
||||
RiuWellLogPlot( RimWellLogPlot* plotDefinition, QWidget* parent );
|
||||
|
||||
bool isScrollbarVisible() const;
|
||||
void setScrollbarVisible( bool visible );
|
||||
void updateVerticalScrollBar( double minVisible, double maxVisible, double minAvailable, double maxAvailable ) override;
|
||||
|
||||
protected:
|
||||
@@ -39,6 +37,7 @@ protected:
|
||||
|
||||
void reinsertScrollbar();
|
||||
void alignScrollbar( int offset );
|
||||
void doRenderTo( QPainter* painter ) override;
|
||||
|
||||
private:
|
||||
RimWellLogPlot* wellLogPlotDefinition();
|
||||
|
||||
@@ -24,12 +24,9 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuWidgetDragger::RiuWidgetDragger( QWidget* widgetToMove,
|
||||
QWidget* widgetToSnapTo /*= nullptr*/,
|
||||
int snapMargins /*= 5*/ )
|
||||
RiuWidgetDragger::RiuWidgetDragger( QWidget* widgetToMove, int snapMargins /*= 5*/ )
|
||||
: QObject( widgetToMove )
|
||||
, m_widgetToMove( widgetToMove )
|
||||
, m_widgetToSnapTo( widgetToSnapTo )
|
||||
, m_snapMargins( snapMargins )
|
||||
, m_startPos( 0, 0 )
|
||||
{
|
||||
@@ -56,61 +53,58 @@ bool RiuWidgetDragger::eventFilter( QObject* watched, QEvent* event )
|
||||
{
|
||||
QPoint relativeMove = mMoveEv->pos() - m_startPos;
|
||||
QRect newFrameRect = m_widgetToMove->frameGeometry().translated( relativeMove );
|
||||
QRect snapToRect = m_widgetToMove->parentWidget()->rect();
|
||||
|
||||
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 )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
newFrameRect.moveLeft( snapToTopLeft.x() + m_snapMargins );
|
||||
}
|
||||
if ( std::abs( diff.y() ) < 4 * 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 );
|
||||
}
|
||||
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 )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
newFrameRect.moveLeft( snapToBottomLeft.x() + m_snapMargins );
|
||||
}
|
||||
if ( std::abs( diff.y() ) < 4 * 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 );
|
||||
}
|
||||
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() );
|
||||
|
||||
@@ -28,14 +28,13 @@ class RiuWidgetDragger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RiuWidgetDragger( QWidget* widgetToMove, QWidget* widgetToSnapTo = nullptr, int snapMargins = 5 );
|
||||
RiuWidgetDragger( QWidget* widgetToMove, int snapMargins = 5 );
|
||||
|
||||
void addWidget( QWidget* widget );
|
||||
bool eventFilter( QObject* watched, QEvent* event ) override;
|
||||
|
||||
private:
|
||||
QPointer<QWidget> m_widgetToMove;
|
||||
QPointer<QWidget> m_widgetToSnapTo;
|
||||
int m_snapMargins;
|
||||
QPoint m_startPos;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user