ResInsight/ApplicationLibCode/UserInterface/RiuQwtPlotLegend.cpp
Kristian Bendiksen 48c6517305 #10785 Work-around for legend item disappearing when highlighted
Seen on Linux only. The legend item would be wider than anticipated by the
layout (for unknown reasons), and would be place on the next line.
Added extra with to the size hint to work around the problem.
2023-11-13 13:29:07 +01:00

152 lines
5.4 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 "RiuQwtPlotLegend.h"
#include "RiuQwtPlotWidget.h"
#include "qwt_dyngrid_layout.h"
#include "qwt_legend_label.h"
#include "qwt_plot.h"
#include "qwt_plot_item.h"
#include <QDebug>
#include <QResizeEvent>
#include <QScrollArea>
#include <QVariant>
#include <utility>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtPlotLegend::RiuQwtPlotLegend( QWidget* parent /*= nullptr */ )
: QwtLegend( parent )
{
auto* legendLayout = qobject_cast<QwtDynGridLayout*>( contentsWidget()->layout() );
if ( legendLayout )
{
legendLayout->setExpandingDirections( Qt::Horizontal | Qt::Vertical );
legendLayout->setSpacing( 1 );
}
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
QScrollArea* scrollArea = findChild<QScrollArea*>( "QwtLegendView" );
if ( scrollArea ) scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotLegend::resizeEvent( QResizeEvent* event )
{
QWidget::resizeEvent( event );
QSize size = event->size();
// Avoid updating geometry if height is very small
if ( size.height() < 10 ) return;
const QwtDynGridLayout* legendLayout = qobject_cast<QwtDynGridLayout*>( contentsWidget()->layout() );
if ( legendLayout )
{
updateGeometry();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuQwtPlotLegend::sizeHint() const
{
QSize fullSizeHint = QwtLegend::sizeHint();
const QwtDynGridLayout* legendLayout = qobject_cast<QwtDynGridLayout*>( contentsWidget()->layout() );
if ( legendLayout )
{
QMargins margins = contentsMargins();
auto widgetSize = size();
int numColumns = std::max( 1, (int)legendLayout->columnsForWidth( widgetSize.width() - margins.left() - margins.right() ) );
int numRows = legendLayout->itemCount() / numColumns;
if ( numRows == 0 )
{
return { 0, 0 };
}
if ( legendLayout->itemCount() % numColumns ) numRows++;
// Extra width to workaround layout issue on linux
// https://github.com/OPM/ResInsight/issues/10785
const int extraWidth = 20;
const int width = numColumns * legendLayout->maxItemWidth() + extraWidth;
int maxHeight = 0;
for ( unsigned int i = 0; i < legendLayout->itemCount(); ++i )
{
auto itemSize = legendLayout->itemAt( i )->sizeHint();
maxHeight = std::max( maxHeight, itemSize.height() );
}
int totalSpacing = ( numRows + 2 ) * legendLayout->spacing() + margins.top() + margins.bottom();
int height = maxHeight * numRows + totalSpacing;
QSize layoutSize( width, height );
QSize frameSize = layoutSize + QSize( 2 * frameWidth(), 2 * frameWidth() );
fullSizeHint.setWidth( std::max( fullSizeHint.width(), frameSize.width() ) );
fullSizeHint.setHeight( std::max( fullSizeHint.height(), frameSize.height() ) );
}
return fullSizeHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotLegend::updateLegend( const QVariant& variant, const QList<QwtLegendData>& legendItems )
{
QwtLegend::updateLegend( variant, legendItems );
emit legendUpdated();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotLegend::updateLegend( const QList<QwtLegendData>& legendData )
{
// Delete all existing widgets
deleteAll();
// Create legend widgets based on legendData
updateLegend( QVariant(), legendData );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuQwtPlotLegend::deleteAll()
{
auto widgets = contentsWidget()->findChildren<QwtLegendLabel*>();
for ( auto w : widgets )
{
w->hide();
w->deleteLater();
}
}