mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 15:14:07 -06:00
213 lines
8.8 KiB
C++
213 lines
8.8 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "cvfScalarMapperDiscreteLinear.h"
|
|
#include "cvfScalarMapperDiscreteLog.h"
|
|
#include "cvfString.h"
|
|
#include "cvfqtUtils.h"
|
|
|
|
#include <QFontMetrics>
|
|
#include <QPaintEvent>
|
|
#include <QPainter>
|
|
|
|
#include <algorithm>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuScalarMapperLegendFrame::RiuScalarMapperLegendFrame( QWidget* parent, const QString& title, cvf::ScalarMapper* scalarMapper )
|
|
: RiuAbstractLegendFrame( parent, title )
|
|
, m_scalarMapper( scalarMapper )
|
|
, m_tickNumberPrecision( 4 )
|
|
, m_numberFormat( RiaNumberFormat::NumberFormatType::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();
|
|
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 - 1.0 * layout->lineSpacing;
|
|
|
|
int colorBarStartY = layout->margins.top() + titleLines.size() * layout->lineSpacing + 1.0 * 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 = std::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];
|
|
return RiaNumberFormat::valueToText( tickValue, m_numberFormat, m_tickNumberPrecision );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
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_tickValues[rectIndexFromBottom] );
|
|
cvf::Color3ub endColor = m_scalarMapper->mapToColor( m_tickValues[rectIndexFromBottom + 1] );
|
|
|
|
if ( dynamic_cast<const cvf::ScalarMapperDiscreteLog*>( m_scalarMapper.p() ) ||
|
|
dynamic_cast<const cvf::ScalarMapperDiscreteLinear*>( m_scalarMapper.p() ) )
|
|
{
|
|
// Do not draw gradient for discrete legends
|
|
endColor = startColor;
|
|
}
|
|
|
|
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 ) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QRect RiuScalarMapperLegendFrame::labelRect( const LayoutInfo& layout, int index ) const
|
|
{
|
|
const int posX = layout.tickEndX + layout.tickTextLeadSpace;
|
|
|
|
QString labelI = this->label( index );
|
|
|
|
int width = this->fontMetrics().boundingRect( labelI ).width() + 4;
|
|
int height = layout.lineSpacing;
|
|
|
|
int posY = layout.colorBarRect.bottom() - layout.tickYPixelPos[index];
|
|
|
|
if ( index + 1 < labelCount() )
|
|
{
|
|
int posYp1 = layout.colorBarRect.bottom() - layout.tickYPixelPos[index + 1];
|
|
height = std::min( height, std::abs( posY - posYp1 ) );
|
|
}
|
|
return QRect( posX, posY - height / 2, width, height );
|
|
}
|