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:
parent
f339b52907
commit
47b93dc0d1
@ -59,9 +59,32 @@ void RiaPreferences::SummaryHistoryCurveStyleModeType::setUp()
|
||||
addItem( RiaPreferences::SYMBOLS_AND_LINES, "SYMBOLS_AND_LINES", "Symbols and Lines" );
|
||||
setDefault( RiaPreferences::SYMBOLS );
|
||||
}
|
||||
|
||||
template <>
|
||||
void RiaPreferences::PageSizeEnum::setUp()
|
||||
{
|
||||
addItem( QPageSize::A3, "A3", "A3" );
|
||||
addItem( QPageSize::A4, "A4", "A4" );
|
||||
addItem( QPageSize::A5, "A5", "A5" );
|
||||
addItem( QPageSize::A6, "A6", "A6" );
|
||||
addItem( QPageSize::Letter, "LETTER", "US Letter" );
|
||||
addItem( QPageSize::Legal, "LEGAL", "US Legal" );
|
||||
addItem( QPageSize::Ledger, "LEDGER", "US Ledger" );
|
||||
addItem( QPageSize::Tabloid, "TABLOID", "US Tabloid" );
|
||||
setDefault( QPageSize::A4 );
|
||||
}
|
||||
|
||||
template <>
|
||||
void RiaPreferences::PageOrientationEnum::setUp()
|
||||
{
|
||||
addItem( QPageLayout::Portrait, "PORTRAIT", "Portrait" );
|
||||
addItem( QPageLayout::Landscape, "LANDSCAPE", "Landscape" );
|
||||
setDefault( QPageLayout::Portrait );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RiaPreferences, "RiaPreferences" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -337,6 +360,19 @@ RiaPreferences::RiaPreferences( void )
|
||||
"",
|
||||
"" );
|
||||
m_useMultipleThreadsWhenLoadingSummaryData.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_pageSize, "pageSize", "Page Size", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_pageOrientation, "pageOrientation", "Page Orientation", "", "", "" );
|
||||
CAF_PDM_InitField( &m_pageLeftMargin, "pageLeftMargin", defaultMarginSize( m_pageSize() ), "Left Margin", "", "", "" );
|
||||
CAF_PDM_InitField( &m_pageTopMargin, "pageTopMargin", defaultMarginSize( m_pageSize() ), "Top Margin", "", "", "" );
|
||||
CAF_PDM_InitField( &m_pageRightMargin, "pageRightMargin", defaultMarginSize( m_pageSize() ), "Right Margin", "", "", "" );
|
||||
CAF_PDM_InitField( &m_pageBottomMargin,
|
||||
"pageBottomMargin",
|
||||
defaultMarginSize( m_pageSize() ),
|
||||
"Bottom Margin",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -467,7 +503,26 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
|
||||
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "Plot Templates" );
|
||||
group->add( &m_plotTemplateFolders );
|
||||
group->add( &m_searchPlotTemplateFoldersRecursively );
|
||||
|
||||
caf::PdmUiGroup* pageSetup = uiOrdering.addNewGroup( "Page Setup" );
|
||||
pageSetup->add( &m_pageSize );
|
||||
pageSetup->add( &m_pageOrientation, false );
|
||||
pageSetup->add( &m_pageLeftMargin );
|
||||
pageSetup->add( &m_pageRightMargin, false );
|
||||
pageSetup->add( &m_pageTopMargin );
|
||||
pageSetup->add( &m_pageBottomMargin, false );
|
||||
|
||||
QString unitLabel = " [mm]";
|
||||
if ( QPageSize( m_pageSize() ).definitionUnits() == QPageSize::Inch )
|
||||
{
|
||||
unitLabel = " [in]";
|
||||
}
|
||||
m_pageLeftMargin.uiCapability()->setUiName( "Left Margin" + unitLabel );
|
||||
m_pageRightMargin.uiCapability()->setUiName( "Right Margin" + unitLabel );
|
||||
m_pageTopMargin.uiCapability()->setUiName( "Top Margin" + unitLabel );
|
||||
m_pageBottomMargin.uiCapability()->setUiName( "Bottom Margin" + unitLabel );
|
||||
}
|
||||
|
||||
else if ( uiConfigName == RiaPreferences::tabNameScripting() )
|
||||
{
|
||||
caf::PdmUiGroup* octaveGroup = uiOrdering.addNewGroup( "Octave" );
|
||||
@ -581,6 +636,21 @@ void RiaPreferences::initAfterRead()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaPreferences::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_pageSize )
|
||||
{
|
||||
m_pageLeftMargin = defaultMarginSize( m_pageSize() );
|
||||
m_pageRightMargin = defaultMarginSize( m_pageSize() );
|
||||
m_pageTopMargin = defaultMarginSize( m_pageSize() );
|
||||
m_pageBottomMargin = defaultMarginSize( m_pageSize() );
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -629,6 +699,22 @@ QString RiaPreferences::tabNameSystem()
|
||||
return "System";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RiaPreferences::defaultMarginSize( QPageSize::PageSizeId pageSizeId )
|
||||
{
|
||||
QPageSize::Unit unit = QPageSize( pageSizeId ).definitionUnits();
|
||||
|
||||
if ( unit == QPageSize::Inch )
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 20.0;
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -851,3 +937,17 @@ void RiaPreferences::writePreferencesToApplicationStore()
|
||||
{
|
||||
caf::PdmSettings::writeFieldsToApplicationStore( this );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QPageLayout RiaPreferences::defaultPageLayout() const
|
||||
{
|
||||
QPageSize pageSize( m_pageSize() );
|
||||
QPageLayout layout( pageSize,
|
||||
m_pageOrientation(),
|
||||
QMarginsF( m_pageLeftMargin, m_pageTopMargin, m_pageRightMargin, m_pageBottomMargin ),
|
||||
(QPageLayout::Unit)pageSize.definitionUnits() );
|
||||
layout.setMode( QPageLayout::StandardMode );
|
||||
return layout;
|
||||
}
|
||||
|
@ -35,6 +35,8 @@
|
||||
// Include to make Pdm work for cvf::Color
|
||||
#include "cafPdmFieldCvfColor.h"
|
||||
|
||||
#include <QPageLayout>
|
||||
#include <QPageSize>
|
||||
#include <QStringList>
|
||||
|
||||
#include <map>
|
||||
@ -66,6 +68,10 @@ public:
|
||||
};
|
||||
typedef caf::AppEnum<SummaryHistoryCurveStyleMode> SummaryHistoryCurveStyleModeType;
|
||||
|
||||
typedef caf::AppEnum<QPageSize::PageSizeId> PageSizeEnum;
|
||||
typedef caf::AppEnum<QPageLayout::Orientation> PageOrientationEnum;
|
||||
|
||||
public:
|
||||
RiaPreferences( void );
|
||||
~RiaPreferences( void ) override;
|
||||
|
||||
@ -97,7 +103,8 @@ public:
|
||||
|
||||
std::map<RiaDefines::FontSettingType, RiaFontCache::FontSize> defaultFontSizes() const;
|
||||
|
||||
void writePreferencesToApplicationStore();
|
||||
void writePreferencesToApplicationStore();
|
||||
QPageLayout defaultPageLayout() const;
|
||||
|
||||
public: // Pdm Fields
|
||||
caf::PdmField<caf::AppEnum<RiaGuiApplication::RINavigationPolicy>> navigationPolicy;
|
||||
@ -156,6 +163,9 @@ protected:
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
void initAfterRead() override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue ) override;
|
||||
|
||||
private:
|
||||
static QString tabNameGeneral();
|
||||
@ -165,6 +175,8 @@ private:
|
||||
static QString tabNameExport();
|
||||
static QString tabNameSystem();
|
||||
|
||||
static double defaultMarginSize( QPageSize::PageSizeId pageSizeId );
|
||||
|
||||
private:
|
||||
caf::PdmChildField<RifReaderSettings*> m_readerSettings;
|
||||
|
||||
@ -184,6 +196,13 @@ private:
|
||||
caf::PdmField<bool> m_showSummaryTimeAsLongString;
|
||||
caf::PdmField<bool> m_useMultipleThreadsWhenLoadingSummaryData;
|
||||
|
||||
caf::PdmField<PageSizeEnum> m_pageSize;
|
||||
caf::PdmField<PageOrientationEnum> m_pageOrientation;
|
||||
caf::PdmField<double> m_pageLeftMargin;
|
||||
caf::PdmField<double> m_pageRightMargin;
|
||||
caf::PdmField<double> m_pageTopMargin;
|
||||
caf::PdmField<double> m_pageBottomMargin;
|
||||
|
||||
caf::PdmField<QString> m_plotTemplateFolders;
|
||||
caf::PdmField<bool> m_searchPlotTemplateFoldersRecursively;
|
||||
caf::PdmField<caf::FilePath> m_defaultPlotTemplate;
|
||||
|
@ -20,8 +20,10 @@
|
||||
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPlotWindowRedrawScheduler.h"
|
||||
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimPlotWindow.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimViewWindow.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
@ -33,9 +35,13 @@
|
||||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QDesktopWidget>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QPageLayout>
|
||||
#include <QPainter>
|
||||
#include <QPdfWriter>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicSnapshotViewToFileFeature, "RicSnapshotViewToFileFeature" );
|
||||
|
||||
@ -72,7 +78,71 @@ void RicSnapshotViewToFileFeature::saveSnapshotAs( const QString& fileName, cons
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSnapshotViewToFileFeature::saveToFile( const QImage& image, const QString& defaultFileBaseName )
|
||||
void RicSnapshotViewToFileFeature::savePlotPDFReportAs( const QString& fileName, RimPlotWindow* plot )
|
||||
{
|
||||
RiaPlotWindowRedrawScheduler::instance()->performScheduledUpdatesAndReplots();
|
||||
QCoreApplication::processEvents();
|
||||
QFile pdfFile( fileName );
|
||||
if ( pdfFile.open( QIODevice::WriteOnly ) )
|
||||
{
|
||||
const int resolution = RiaGuiApplication::instance()->desktop()->logicalDpiX();
|
||||
QPdfWriter pdfPrinter( fileName );
|
||||
pdfPrinter.setPageLayout( plot->pageLayout() );
|
||||
pdfPrinter.setCreator( QCoreApplication::applicationName() );
|
||||
pdfPrinter.setResolution( resolution );
|
||||
QPainter painter( &pdfPrinter );
|
||||
QRect widgetRect = plot->viewWidget()->contentsRect();
|
||||
QRect fullPageRect = pdfPrinter.pageLayout().fullRectPixels( resolution );
|
||||
QRect paintRect = pdfPrinter.pageLayout().paintRectPixels( resolution );
|
||||
plot->viewWidget()->resize( paintRect.size() );
|
||||
plot->renderWindowContent( &painter );
|
||||
plot->viewWidget()->resize( widgetRect.size() );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Could not write PDF to %1" ).arg( fileName ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSnapshotViewToFileFeature::saveViewWindowToFile( RimViewWindow* viewWindow,
|
||||
const QString& defaultFileBaseName /*= "image" */ )
|
||||
{
|
||||
RimPlotWindow* plotWindow = dynamic_cast<RimPlotWindow*>( viewWindow );
|
||||
|
||||
QString fileName = generateSaveFileName( defaultFileBaseName, plotWindow != nullptr );
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
if ( plotWindow && fileName.endsWith( "PDF", Qt::CaseInsensitive ) )
|
||||
{
|
||||
savePlotPDFReportAs( fileName, plotWindow );
|
||||
}
|
||||
else
|
||||
{
|
||||
RicSnapshotViewToFileFeature::saveSnapshotAs( fileName, viewWindow->snapshotWindowContent() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSnapshotViewToFileFeature::saveImageToFile( const QImage& image, const QString& defaultFileBaseName )
|
||||
{
|
||||
QString fileName = generateSaveFileName( defaultFileBaseName, false );
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
RicSnapshotViewToFileFeature::saveSnapshotAs( fileName, image );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RicSnapshotViewToFileFeature::generateSaveFileName( const QString& defaultFileBaseName /*= "image"*/,
|
||||
bool supportPDF /*= false */ )
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
RimProject* proj = app->project();
|
||||
@ -88,17 +158,30 @@ void RicSnapshotViewToFileFeature::saveToFile( const QImage& image, const QStrin
|
||||
startPath = app->lastUsedDialogDirectory( "IMAGE_SNAPSHOT" );
|
||||
}
|
||||
|
||||
QString defaultAbsFileName = caf::Utils::constructFullFileName( startPath, defaultFileBaseName, ".png" );
|
||||
QString fileName = QFileDialog::getSaveFileName( nullptr, tr( "Export to File" ), defaultAbsFileName );
|
||||
if ( fileName.isEmpty() )
|
||||
QStringList imageFileExtensions;
|
||||
imageFileExtensions << "*.png"
|
||||
<< "*.jpg"
|
||||
<< "*.bmp"
|
||||
<< "*.pbm"
|
||||
<< "*.pgm";
|
||||
QString fileExtensionFilter = QString( "Images (%1)" ).arg( imageFileExtensions.join( " " ) );
|
||||
|
||||
if ( supportPDF )
|
||||
{
|
||||
return;
|
||||
fileExtensionFilter += ";;PDF report( *.pdf )";
|
||||
}
|
||||
|
||||
// Remember the directory to next time
|
||||
app->setLastUsedDialogDirectory( "IMAGE_SNAPSHOT", QFileInfo( fileName ).absolutePath() );
|
||||
|
||||
RicSnapshotViewToFileFeature::saveSnapshotAs( fileName, image );
|
||||
QString defaultAbsFileName = caf::Utils::constructFullFileName( startPath, defaultFileBaseName, ".png" );
|
||||
QString fileName = QFileDialog::getSaveFileName( nullptr,
|
||||
tr( "Export to File" ),
|
||||
defaultAbsFileName,
|
||||
fileExtensionFilter );
|
||||
if ( !fileName.isEmpty() )
|
||||
{
|
||||
// Remember the directory to next time
|
||||
app->setLastUsedDialogDirectory( "IMAGE_SNAPSHOT", QFileInfo( fileName ).absolutePath() );
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -142,8 +225,7 @@ void RicSnapshotViewToFileFeature::onActionTriggered( bool isChecked )
|
||||
return;
|
||||
}
|
||||
|
||||
QImage image = viewWindow->snapshotWindowContent();
|
||||
saveToFile( image, RicSnapshotFilenameGenerator::generateSnapshotFileName( viewWindow ) );
|
||||
saveViewWindowToFile( viewWindow, RicSnapshotFilenameGenerator::generateSnapshotFileName( viewWindow ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
|
||||
class RimPlotWindow;
|
||||
class RimViewWindow;
|
||||
class QImage;
|
||||
|
||||
@ -31,9 +32,13 @@ class RicSnapshotViewToFileFeature : public caf::CmdFeature
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
static void saveSnapshotAs( const QString& fileName, RimViewWindow* viewWindow );
|
||||
static void saveSnapshotAs( const QString& fileName, const QImage& image );
|
||||
static void saveToFile( const QImage& image, const QString& defaultFileBaseName = "image" );
|
||||
static void saveSnapshotAs( const QString& fileName, RimViewWindow* viewWindow );
|
||||
static void saveSnapshotAs( const QString& fileName, const QImage& image );
|
||||
static void savePlotPDFReportAs( const QString& fileName, RimPlotWindow* plotWindow );
|
||||
|
||||
static void saveViewWindowToFile( RimViewWindow* viewWindow, const QString& defaultFileBaseName = "image" );
|
||||
static void saveImageToFile( const QImage& image, const QString& defaultFileBaseName = "image" );
|
||||
static QString generateSaveFileName( const QString& defaultFileBaseName = "image", bool supportPDF = false );
|
||||
static QIcon icon();
|
||||
static QString text();
|
||||
|
||||
|
@ -333,5 +333,5 @@ void RicGridStatisticsDialog::slotScreenShotToFile()
|
||||
{
|
||||
defaultFileBaseName = "Snapshot_Statistics";
|
||||
}
|
||||
RicSnapshotViewToFileFeature::saveToFile( snapshotImage, defaultFileBaseName );
|
||||
RicSnapshotViewToFileFeature::saveImageToFile( snapshotImage, defaultFileBaseName );
|
||||
}
|
||||
|
@ -19,4 +19,5 @@ setup(
|
||||
license=license,
|
||||
packages=['rips'],
|
||||
package_data={'rips': ['*.py', 'generated/*.py', 'PythonExamples/*.py', 'tests/*.py']}
|
||||
install_requires=['grpcio>=1.20.0']
|
||||
)
|
@ -56,6 +56,7 @@
|
||||
#include "RimWellPltPlot.h"
|
||||
|
||||
#include "RiuCvfOverlayItemWidget.h"
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "cafPdmUiListEditor.h"
|
||||
@ -1268,10 +1269,12 @@ void RimWellRftPlot::defineCurveColorsAndSymbols( const std::set<RiaRftPltCurveD
|
||||
{
|
||||
if ( !m_ensembleLegendFrames[curveSet] )
|
||||
{
|
||||
m_ensembleLegendFrames[curveSet] = new RiuCvfOverlayItemWidget( track->viewer(),
|
||||
track->viewer()->canvas() );
|
||||
m_ensembleLegendFrames[curveSet] =
|
||||
new RiuCvfOverlayItemWidget( curveSet->legendConfig()->titledOverlayFrame(),
|
||||
track->viewer()->canvas(),
|
||||
track->viewer()->overlayMargins() );
|
||||
}
|
||||
m_ensembleLegendFrames[curveSet]->updateFromOverlayItem( curveSet->legendConfig()->titledOverlayFrame() );
|
||||
|
||||
track->viewer()->addOverlayFrame( m_ensembleLegendFrames[curveSet] );
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class RigEclipseCaseData;
|
||||
class RiaRftPltCurveDefinition;
|
||||
class RifDataSourceForRftPlt;
|
||||
class RifEclipseRftAddress;
|
||||
class RiuCvfOverlayItemWidget;
|
||||
class RiuDraggableOverlayFrame;
|
||||
|
||||
namespace cvf
|
||||
{
|
||||
@ -156,8 +156,8 @@ private:
|
||||
|
||||
caf::PdmPtrField<RimWellPathCollection*> m_wellPathCollection;
|
||||
|
||||
caf::PdmChildArrayField<RimWellRftEnsembleCurveSet*> m_ensembleCurveSets;
|
||||
std::map<RimWellRftEnsembleCurveSet*, QPointer<RiuCvfOverlayItemWidget>> m_ensembleLegendFrames;
|
||||
caf::PdmChildArrayField<RimWellRftEnsembleCurveSet*> m_ensembleCurveSets;
|
||||
std::map<RimWellRftEnsembleCurveSet*, QPointer<RiuDraggableOverlayFrame>> m_ensembleLegendFrames;
|
||||
|
||||
std::map<RifDataSourceForRftPlt, cvf::Color3f> m_dataSourceColors;
|
||||
std::map<QDateTime, RiuQwtSymbol::PointSymbolEnum> m_timeStepSymbols;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RifTextDataTableFormatter.h"
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
#include "RiuGridCrossQwtPlot.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
@ -276,6 +277,37 @@ bool RimGridCrossPlot::showInfoBox() const
|
||||
return m_showInfoBox();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::updateInfoBox()
|
||||
{
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
if ( m_showInfoBox )
|
||||
{
|
||||
if ( !m_infoBox )
|
||||
{
|
||||
m_infoBox = new RiuDraggableOverlayFrame( m_plotWidget->canvas(), m_plotWidget->overlayMargins() );
|
||||
m_infoBox->setAnchorCorner( RiuDraggableOverlayFrame::AnchorCorner::TopRight );
|
||||
RiuTextOverlayContentFrame* textFrame = new RiuTextOverlayContentFrame( m_infoBox );
|
||||
textFrame->setText( generateInfoBoxText() );
|
||||
m_infoBox->setContentFrame( textFrame );
|
||||
}
|
||||
m_plotWidget->addOverlayFrame( m_infoBox );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_plotWidget && m_infoBox )
|
||||
{
|
||||
m_plotWidget->removeOverlayFrame( m_infoBox );
|
||||
delete m_infoBox;
|
||||
m_infoBox = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -355,28 +387,6 @@ void RimGridCrossPlot::onAxisSelected( int axis, bool toggle )
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSet )
|
||||
{
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->addOrUpdateDataSetLegend( dataSet );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimGridCrossPlot::removeDataSetLegend( RimGridCrossPlotDataSet* dataSet )
|
||||
{
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->removeDataSetLegend( dataSet );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -391,6 +401,38 @@ void RimGridCrossPlot::doRemoveFromCollection()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimGridCrossPlot::generateInfoBoxText() const
|
||||
{
|
||||
QStringList curveInfoTexts;
|
||||
for ( auto dataSet : dataSets() )
|
||||
{
|
||||
QString curveInfoText = dataSet->infoText();
|
||||
if ( dataSet->isChecked() && !curveInfoText.isEmpty() )
|
||||
{
|
||||
curveInfoTexts += curveInfoText;
|
||||
}
|
||||
}
|
||||
QStringList infoText;
|
||||
infoText << QString( "<b>View ID:</b> %1<br/>" ).arg( 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();
|
||||
}
|
||||
return infoText.join( "\n" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -404,9 +446,9 @@ QWidget* RimGridCrossPlot::createViewWidget( QWidget* mainWindowParent )
|
||||
{
|
||||
dataSet->setParentQwtPlotNoReplot( m_plotWidget );
|
||||
}
|
||||
m_plotWidget->scheduleReplot();
|
||||
}
|
||||
|
||||
m_plotWidget->scheduleReplot();
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
@ -433,6 +475,7 @@ void RimGridCrossPlot::onLoadDataAndUpdate()
|
||||
|
||||
updateCurveNamesAndPlotTitle();
|
||||
updatePlot();
|
||||
updateInfoBox();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -724,6 +767,7 @@ bool RimGridCrossPlot::applyFontSize( RiaDefines::FontSettingType fontSettingTyp
|
||||
if ( forceChange || legendFontSize() == oldFontSize )
|
||||
{
|
||||
setLegendFontSize( fontSize );
|
||||
|
||||
anyChange = true;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
class RimPlotAxisPropertiesInterface;
|
||||
class RimPlotAxisProperties;
|
||||
class RimGridCrossPlotDataSet;
|
||||
class RiuDraggableOverlayFrame;
|
||||
class RiuGridCrossQwtPlot;
|
||||
|
||||
class RimGridCrossPlotNameConfig : public RimNameConfig
|
||||
@ -76,6 +77,7 @@ public:
|
||||
QString createAutoName() const override;
|
||||
|
||||
bool showInfoBox() const;
|
||||
void updateInfoBox();
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
void detachAllCurves() override;
|
||||
@ -109,9 +111,6 @@ public:
|
||||
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override;
|
||||
void onAxisSelected( int axis, bool toggle ) override;
|
||||
|
||||
void addOrUpdateDataSetLegend( RimGridCrossPlotDataSet* dataSet );
|
||||
void removeDataSetLegend( RimGridCrossPlotDataSet* dataSet );
|
||||
|
||||
protected:
|
||||
QWidget* createViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
void deleteViewWidget() override;
|
||||
@ -146,7 +145,8 @@ private:
|
||||
void doUpdateLayout() override;
|
||||
void cleanupBeforeClose();
|
||||
|
||||
void doRemoveFromCollection() override;
|
||||
void doRemoveFromCollection() override;
|
||||
QString generateInfoBoxText() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showInfoBox;
|
||||
@ -158,5 +158,6 @@ private:
|
||||
|
||||
caf::PdmChildArrayField<RimGridCrossPlotDataSet*> m_crossPlotDataSets;
|
||||
|
||||
QPointer<RiuGridCrossQwtPlot> m_plotWidget;
|
||||
QPointer<RiuGridCrossQwtPlot> m_plotWidget;
|
||||
QPointer<RiuDraggableOverlayFrame> m_infoBox;
|
||||
};
|
||||
|
@ -33,7 +33,9 @@
|
||||
#include "RigFormationNames.h"
|
||||
#include "RigMainGrid.h"
|
||||
|
||||
#include "RiuCvfOverlayItemWidget.h"
|
||||
#include "RiuGridCrossQwtPlot.h"
|
||||
#include "RiuScalarMapperLegendFrame.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
@ -57,6 +59,7 @@
|
||||
#include "cafPdmUiSliderEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cafProgressInfo.h"
|
||||
#include "cafTitledOverlayFrame.h"
|
||||
#include "cvfScalarMapper.h"
|
||||
#include "cvfqtUtils.h"
|
||||
|
||||
@ -133,6 +136,18 @@ RimGridCrossPlotDataSet::RimGridCrossPlotDataSet()
|
||||
setDefaults();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimGridCrossPlotDataSet::~RimGridCrossPlotDataSet()
|
||||
{
|
||||
if ( m_legendOverlayFrame )
|
||||
{
|
||||
m_legendOverlayFrame->setParent( nullptr );
|
||||
delete m_legendOverlayFrame;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1020,11 +1035,20 @@ void RimGridCrossPlotDataSet::updateLegendRange()
|
||||
m_groupingProperty->updateRangesForEmbeddedLegends( m_timeStep() );
|
||||
}
|
||||
}
|
||||
parent->addOrUpdateDataSetLegend( this );
|
||||
if ( !m_legendOverlayFrame )
|
||||
{
|
||||
m_legendOverlayFrame = new RiuDraggableOverlayFrame( parent->viewer()->canvas(),
|
||||
parent->viewer()->overlayMargins() );
|
||||
}
|
||||
m_legendOverlayFrame->setContentFrame( legendConfig()->makeLegendFrame() );
|
||||
parent->viewer()->addOverlayFrame( m_legendOverlayFrame );
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->removeDataSetLegend( this );
|
||||
if ( m_legendOverlayFrame )
|
||||
{
|
||||
parent->viewer()->removeOverlayFrame( m_legendOverlayFrame );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <cvfArray.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <map>
|
||||
|
||||
class RifTextDataTableFormatter;
|
||||
@ -47,11 +48,12 @@ class RimEclipseResultCase;
|
||||
class RimEclipseCellColors;
|
||||
class RimEclipseResultDefinition;
|
||||
class RimRegularLegendConfig;
|
||||
class RimPlotCellFilterCollection;
|
||||
class RimPlotCellFilter;
|
||||
class RiuDraggableOverlayFrame;
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
class QString;
|
||||
class RimPlotCellFilterCollection;
|
||||
class RimPlotCellFilter;
|
||||
|
||||
class RimGridCrossPlotDataSetNameConfig : public RimNameConfig
|
||||
{
|
||||
@ -93,7 +95,7 @@ public:
|
||||
|
||||
public:
|
||||
RimGridCrossPlotDataSet();
|
||||
~RimGridCrossPlotDataSet() = default;
|
||||
~RimGridCrossPlotDataSet();
|
||||
|
||||
void setCellFilterView( RimGridView* cellFilterView );
|
||||
void loadDataAndUpdate( bool updateParentPlot );
|
||||
@ -188,5 +190,6 @@ private:
|
||||
caf::PdmField<bool> m_useCustomColor;
|
||||
caf::PdmField<cvf::Color3f> m_customColor;
|
||||
caf::PdmChildField<RimPlotCellFilterCollection*> m_plotCellFilterCollection;
|
||||
;
|
||||
|
||||
QPointer<RiuDraggableOverlayFrame> m_legendOverlayFrame;
|
||||
};
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "RiuPlotMainWindow.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <cvfAssert.h>
|
||||
@ -299,6 +300,17 @@ void RimMultiPlotWindow::doSetAutoScaleYEnabled( bool enabled )
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimMultiPlotWindow::doRenderWindowContent( QPainter* painter )
|
||||
{
|
||||
if ( m_viewer )
|
||||
{
|
||||
m_viewer->renderTo( painter );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -426,10 +438,10 @@ QImage RimMultiPlotWindow::snapshotWindowContent()
|
||||
|
||||
if ( m_viewer )
|
||||
{
|
||||
m_viewer->setSelectionsVisible( false );
|
||||
QPixmap pix = m_viewer->grab();
|
||||
image = pix.toImage();
|
||||
m_viewer->setSelectionsVisible( true );
|
||||
QPixmap pix( m_viewer->size() );
|
||||
QPainter painter( &pix );
|
||||
m_viewer->renderTo( &painter );
|
||||
image = pix.toImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
|
@ -129,6 +129,7 @@ private:
|
||||
virtual void updateSubPlotNames();
|
||||
virtual void updatePlotWindowTitle();
|
||||
virtual void doSetAutoScaleYEnabled( bool enabled );
|
||||
void doRenderWindowContent( QPainter* painter ) override;
|
||||
|
||||
protected:
|
||||
caf::PdmField<bool> m_showPlotWindowTitle;
|
||||
|
@ -123,3 +123,14 @@ void RimPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const Q
|
||||
updateParentLayout();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlot::doRenderWindowContent( QPainter* painter )
|
||||
{
|
||||
if ( viewer() )
|
||||
{
|
||||
viewer()->renderTo( painter, viewer()->frameGeometry() );
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ protected:
|
||||
|
||||
private:
|
||||
virtual void doRemoveFromCollection() = 0;
|
||||
virtual void doRenderWindowContent( QPainter* painter );
|
||||
|
||||
protected:
|
||||
caf::PdmField<RowOrColSpanEnum> m_rowSpan;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "RimPlotWindow.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaPlotWindowRedrawScheduler.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RicfCommandObject.h"
|
||||
@ -26,6 +27,8 @@
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlotWindow, "RimPlotWindow" ); // Do not use. Abstract class
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -153,6 +156,28 @@ void RimPlotWindow::updateParentLayout()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotWindow::renderWindowContent( QPainter* painter )
|
||||
{
|
||||
doRenderWindowContent( painter );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QPageLayout RimPlotWindow::pageLayout() const
|
||||
{
|
||||
QPageLayout defaultPageLayout = RiaApplication::instance()->preferences()->defaultPageLayout();
|
||||
QPageLayout customPageLayout;
|
||||
if ( hasCustomPageLayout( &customPageLayout ) )
|
||||
{
|
||||
return customPageLayout;
|
||||
}
|
||||
return defaultPageLayout;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -218,6 +243,14 @@ void RimPlotWindow::uiOrderingForLegendSettings( QString uiConfigName, caf::PdmU
|
||||
uiOrdering.add( &m_legendFontSize );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Re-implement this in sub classes to provide a custom page layout for printing/PDF
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimPlotWindow::hasCustomPageLayout( QPageLayout* customPageLayout ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <QPageLayout>
|
||||
|
||||
class RimProject;
|
||||
|
||||
class QwtPlotCurve;
|
||||
@ -57,6 +59,9 @@ public:
|
||||
void updateLayout();
|
||||
void updateParentLayout();
|
||||
|
||||
void renderWindowContent( QPainter* painter );
|
||||
QPageLayout pageLayout() const;
|
||||
|
||||
protected:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
@ -69,6 +74,8 @@ protected:
|
||||
|
||||
private:
|
||||
virtual void doUpdateLayout() {}
|
||||
virtual bool hasCustomPageLayout( QPageLayout* customPageLayout ) const;
|
||||
virtual void doRenderWindowContent( QPainter* painter ) = 0;
|
||||
|
||||
private:
|
||||
friend class RimProject;
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "RimWellMeasurementInView.h"
|
||||
#include "RimWellRftEnsembleCurveSet.h"
|
||||
#include "RimWellRftPlot.h"
|
||||
#include "RiuCategoryLegendFrame.h"
|
||||
#include "RiuScalarMapperLegendFrame.h"
|
||||
|
||||
#include "cafCategoryLegend.h"
|
||||
#include "cafCategoryMapper.h"
|
||||
@ -148,6 +150,7 @@ RimRegularLegendConfig::RimRegularLegendConfig()
|
||||
"",
|
||||
"The number of significant digits displayed in the legend numbers",
|
||||
"" );
|
||||
m_significantDigitsInData = m_precision;
|
||||
CAF_PDM_InitField( &m_tickNumberFormat,
|
||||
"TickNumberFormat",
|
||||
caf::AppEnum<RimRegularLegendConfig::NumberFormatType>( FIXED ),
|
||||
@ -312,6 +315,8 @@ void RimRegularLegendConfig::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRegularLegendConfig::updateLegend()
|
||||
{
|
||||
m_significantDigitsInData = m_precision;
|
||||
|
||||
double adjustedMin = cvf::UNDEFINED_DOUBLE;
|
||||
double adjustedMax = cvf::UNDEFINED_DOUBLE;
|
||||
|
||||
@ -461,7 +466,9 @@ void RimRegularLegendConfig::updateLegend()
|
||||
{
|
||||
numDecimalDigits -= static_cast<int>( decadesInRange );
|
||||
}
|
||||
m_scalarMapperLegend->setTickPrecision( cvf::Math::clamp( numDecimalDigits, 0, 20 ) );
|
||||
numDecimalDigits = cvf::Math::clamp( numDecimalDigits, 0, 20 );
|
||||
m_significantDigitsInData = numDecimalDigits;
|
||||
m_scalarMapperLegend->setTickPrecision( numDecimalDigits );
|
||||
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
RiaPreferences* preferences = app->preferences();
|
||||
@ -762,7 +769,9 @@ double RimRegularLegendConfig::categoryValueFromCategoryName( const QString& cat
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimRegularLegendConfig::setTitle( const QString& title )
|
||||
{
|
||||
auto cvfTitle = cvfqt::Utils::toString( title );
|
||||
m_title = title;
|
||||
|
||||
auto cvfTitle = cvfqt::Utils::toString( m_title );
|
||||
m_scalarMapperLegend->setTitle( cvfTitle );
|
||||
m_categoryLegend->setTitle( cvfTitle );
|
||||
}
|
||||
@ -805,6 +814,24 @@ const caf::TitledOverlayFrame* RimRegularLegendConfig::titledOverlayFrame() cons
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuAbstractLegendFrame* RimRegularLegendConfig::makeLegendFrame()
|
||||
{
|
||||
if ( m_currentScalarMapper == m_categoryMapper )
|
||||
{
|
||||
return new RiuCategoryLegendFrame( nullptr, m_title, m_categoryMapper.p() );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto legend = new RiuScalarMapperLegendFrame( nullptr, m_title, m_currentScalarMapper.p() );
|
||||
legend->setTickFormat( m_tickNumberFormat() );
|
||||
legend->setTickPrecision( m_significantDigitsInData );
|
||||
return legend;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -48,6 +48,7 @@ class OverlayScalarMapperLegend;
|
||||
|
||||
class Rim3dView;
|
||||
class RimEnsembleCurveSet;
|
||||
class RiuAbstractLegendFrame;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -148,6 +149,7 @@ public:
|
||||
|
||||
const caf::TitledOverlayFrame* titledOverlayFrame() const override;
|
||||
caf::TitledOverlayFrame* titledOverlayFrame() override;
|
||||
RiuAbstractLegendFrame* makeLegendFrame();
|
||||
|
||||
RangeModeType rangeMode() const;
|
||||
static cvf::Color3ubArray colorArrayFromColorType( ColorRangesType colorType );
|
||||
@ -170,9 +172,6 @@ private:
|
||||
|
||||
friend class RimViewLinker;
|
||||
|
||||
caf::OverlayScalarMapperLegend* getOrCreateScalarMapperLegend();
|
||||
caf::CategoryLegend* getOrCreateCategoryLegend();
|
||||
|
||||
private:
|
||||
cvf::ref<cvf::ScalarMapperDiscreteLinear> m_linDiscreteScalarMapper;
|
||||
cvf::ref<cvf::ScalarMapperDiscreteLog> m_logDiscreteScalarMapper;
|
||||
@ -211,4 +210,7 @@ private:
|
||||
caf::PdmField<double> m_userDefinedMinValue;
|
||||
caf::PdmField<caf::AppEnum<ColorRangesType>> m_colorRangeMode;
|
||||
caf::PdmField<caf::AppEnum<MappingType>> m_mappingMode;
|
||||
|
||||
QString m_title;
|
||||
int m_significantDigitsInData;
|
||||
};
|
||||
|
@ -693,26 +693,6 @@ void RimWellLogPlot::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RimWellLogPlot::snapshotWindowContent()
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if ( m_viewer )
|
||||
{
|
||||
RiuWellLogPlot* wellLogViewer = dynamic_cast<RiuWellLogPlot*>( m_viewer.data() );
|
||||
CAF_ASSERT( wellLogViewer );
|
||||
bool isScrollbarVisible = wellLogViewer->isScrollbarVisible();
|
||||
wellLogViewer->setScrollbarVisible( false );
|
||||
image = RimMultiPlotWindow::snapshotWindowContent();
|
||||
wellLogViewer->setScrollbarVisible( isScrollbarVisible );
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -122,8 +122,6 @@ protected:
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
QImage snapshotWindowContent() override;
|
||||
|
||||
private:
|
||||
void updateSubPlotNames() override;
|
||||
void updatePlotWindowTitle() override;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaStatisticsTools.h"
|
||||
#include "RiuAbstractLegendFrame.h"
|
||||
|
||||
#include "SummaryPlotCommands/RicSummaryCurveCreator.h"
|
||||
|
||||
@ -47,6 +48,7 @@
|
||||
#include "RimSummaryPlot.h"
|
||||
|
||||
#include "RiuCvfOverlayItemWidget.h"
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuSummaryCurveDefSelectionDialog.h"
|
||||
@ -383,7 +385,7 @@ RimRegularLegendConfig* RimEnsembleCurveSet::legendConfig()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QFrame* RimEnsembleCurveSet::legendFrame() const
|
||||
RiuDraggableOverlayFrame* RimEnsembleCurveSet::legendFrame() const
|
||||
{
|
||||
return m_legendOverlayFrame;
|
||||
}
|
||||
@ -888,10 +890,10 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
{
|
||||
if ( !m_legendOverlayFrame )
|
||||
{
|
||||
m_legendOverlayFrame = new RiuCvfOverlayItemWidget( plot->viewer(), plot->viewer()->canvas() );
|
||||
m_legendOverlayFrame = new RiuDraggableOverlayFrame( plot->viewer()->canvas(),
|
||||
plot->viewer()->overlayMargins() );
|
||||
}
|
||||
m_legendOverlayFrame->updateFromOverlayItem( m_legendConfig()->titledOverlayFrame() );
|
||||
plot->viewer()->addOverlayFrame( m_legendOverlayFrame );
|
||||
m_legendOverlayFrame->setContentFrame( m_legendConfig->makeLegendFrame() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ class RimSummaryCurveAutoName;
|
||||
class RimEnsembleCurveFilterCollection;
|
||||
class RimEnsembleStatistics;
|
||||
class RimEnsembleStatisticsCase;
|
||||
class RiuCvfOverlayItemWidget;
|
||||
class RiuDraggableOverlayFrame;
|
||||
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
@ -108,8 +108,8 @@ public:
|
||||
|
||||
RimRegularLegendConfig* legendConfig();
|
||||
|
||||
void updateEnsembleLegendItem();
|
||||
QFrame* legendFrame() const;
|
||||
void updateEnsembleLegendItem();
|
||||
RiuDraggableOverlayFrame* legendFrame() const;
|
||||
|
||||
void updateAllCurves();
|
||||
void updateStatisticsCurves();
|
||||
@ -190,8 +190,8 @@ private:
|
||||
caf::PdmProxyValueField<QString> m_autoGeneratedName;
|
||||
caf::PdmChildField<RimSummaryCurveAutoName*> m_summaryAddressNameTools;
|
||||
|
||||
QwtPlotCurve* m_qwtPlotCurveForLegendText;
|
||||
QPointer<RiuCvfOverlayItemWidget> m_legendOverlayFrame;
|
||||
QwtPlotCurve* m_qwtPlotCurveForLegendText;
|
||||
QPointer<RiuDraggableOverlayFrame> m_legendOverlayFrame;
|
||||
|
||||
std::unique_ptr<RimEnsembleStatisticsCase> m_ensembleStatCase;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "cafInternalLegendRenderTools.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace cvf;
|
||||
|
||||
|
@ -38,13 +38,13 @@ public:
|
||||
void majorTickValues(std::vector<double>* domainValues) const override;
|
||||
double normalizedValue(double domainValue) const override;
|
||||
double domainValue(double normalizedValue) const override;
|
||||
size_t categoryCount() const;
|
||||
|
||||
const cvf::String textForCategoryIndex(size_t index) const;
|
||||
int categoryIndexForCategory(double domainValue) const;
|
||||
|
||||
private:
|
||||
friend class CategoryLegend;
|
||||
size_t categoryCount() const;
|
||||
const cvf::String textForCategoryIndex(size_t index) const;
|
||||
|
||||
int categoryIndexForCategory(double domainValue) const;
|
||||
void recomputeMaxTexCoord();
|
||||
|
||||
private:
|
||||
|
@ -682,7 +682,7 @@ cvf::Vec2ui OverlayScalarMapperLegend::preferredSize()
|
||||
OverlayColorLegendLayoutInfo layout({200,200}); // Use default size
|
||||
layoutInfo(&layout);
|
||||
|
||||
float prefferredYSize = 2 * layout.margins.y()
|
||||
float preferredYSize = 2 * layout.margins.y()
|
||||
+ layout.lineSpacing * this->titleStrings().size()
|
||||
+ 1.5f * layout.lineSpacing * m_tickValues.size();
|
||||
|
||||
@ -706,18 +706,17 @@ cvf::Vec2ui OverlayScalarMapperLegend::preferredSize()
|
||||
maxTickTextWidth = maxTickTextWidth < textWidth ? textWidth : maxTickTextWidth;
|
||||
}
|
||||
|
||||
float prefferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
|
||||
float preferredXSize = layout.tickEndX + layout.margins.x() + layout.tickTextLeadSpace + maxTickTextWidth;
|
||||
|
||||
for (const cvf::String& titleLine : titleStrings())
|
||||
{
|
||||
float titleWidth = this->font()->textExtent(titleLine).x() + 2*layout.margins.x();
|
||||
prefferredXSize = prefferredXSize < titleWidth ? titleWidth : prefferredXSize;
|
||||
preferredXSize = preferredXSize < titleWidth ? titleWidth : preferredXSize;
|
||||
}
|
||||
|
||||
prefferredXSize = std::min(prefferredXSize, 400.0f);
|
||||
|
||||
return { (unsigned int)(std::ceil(prefferredXSize)), (unsigned int)(std::ceil(prefferredYSize)) };
|
||||
preferredXSize = std::min(preferredXSize, 400.0f);
|
||||
|
||||
return { (unsigned int)(std::ceil(preferredXSize)), (unsigned int)(std::ceil(preferredYSize)) };
|
||||
}
|
||||
|
||||
} // namespace cvf
|
||||
|
@ -218,4 +218,4 @@ namespace caf {
|
||||
{
|
||||
return m_font.p();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
ThirdParty/Qwt/src/qwt_plot_canvas.cpp
vendored
2
ThirdParty/Qwt/src/qwt_plot_canvas.cpp
vendored
@ -730,7 +730,7 @@ void QwtPlotCanvas::paintEvent( QPaintEvent *event )
|
||||
QPainter painter( this );
|
||||
painter.setClipRegion( event->region() );
|
||||
|
||||
if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) &&
|
||||
if (testPaintAttribute( QwtPlotCanvas::BackingStore ) &&
|
||||
d_data->backingStore != NULL )
|
||||
{
|
||||
QPixmap &bs = *d_data->backingStore;
|
||||
|
Loading…
Reference in New Issue
Block a user