Files
ResInsight/ApplicationLibCode/ProjectDataModel/RimViewWindow.cpp
T

465 lines
17 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016 Statoil 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 "RimViewWindow.h"
#include "RiaColorTables.h"
#include "RiaColorTools.h"
2019-05-06 10:36:05 +02:00
#include "RiaGuiApplication.h"
#include "RiaPreferencesSystem.h"
#include "RicfCommandObject.h"
2026-04-30 17:45:45 +02:00
#include "RimDockWindowController.h"
#include "RimPlotAxisPropertiesInterface.h"
2026-05-19 18:08:18 +02:00
#include "RiuDockWidgetTools.h"
#include "cafPdmUiTreeAttributes.h"
#include "DockManager.h"
2026-05-05 00:10:08 +02:00
#include "DockWidget.h"
#include <QApplication>
#include <QImage>
#include <QPainter>
#include <QPixmap>
#include <QWidget>
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimViewWindow, "ViewWindow" ); // Do not use. Abstract class
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2023-04-14 14:07:45 +02:00
RimViewWindow::RimViewWindow()
2026-05-05 00:10:08 +02:00
: m_dockWidget( nullptr )
, m_isActiveViewer( false )
{
2023-02-26 10:48:40 +01:00
CAF_PDM_InitScriptableObjectWithNameAndComment( "View window", "", "", "", "ViewWindow", "The Base Class for all Views and Plots in ResInsight" );
CAF_PDM_InitFieldNoDefault( &m_windowController, "WindowController", "" );
m_windowController.uiCapability()->setUiTreeChildrenHidden( true );
CAF_PDM_InitField( &m_showWindow, "ShowWindow", true, "Show Window" );
m_showWindow.uiCapability()->setUiHidden( true );
2026-06-02 00:55:26 +02:00
CAF_PDM_InitField( &m_dockWindowId, "DockWindowId", QString(), "Dock Window Id" );
2026-06-02 00:55:26 +02:00
m_dockWindowId.uiCapability()->setUiHidden( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2023-04-14 14:07:45 +02:00
RimViewWindow::~RimViewWindow()
{
2026-06-11 16:30:46 +02:00
if ( m_windowController() ) delete m_windowController();
}
2019-11-15 10:12:19 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::showWindow() const
{
return m_showWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::setShowWindow( bool showWindow )
{
m_showWindow = showWindow;
}
2026-05-19 02:26:59 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::setAsActiveViewer( bool allowSelectionChange )
2026-05-19 02:26:59 +02:00
{
if ( m_windowController ) m_windowController->setAsActiveViewer( allowSelectionChange );
2026-05-19 02:26:59 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::loadDataAndUpdate()
{
2019-11-14 20:48:11 +01:00
assignIdIfNecessary();
onLoadDataAndUpdate();
updateUiIconFromToggleField();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isMainDockedWindow() const
{
return m_windowController != nullptr;
}
2026-05-18 13:39:38 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isDockedIn3DView() const
{
return ( m_windowController != nullptr ) && ( m_windowController->mainWindowId() == RimDockWindowController::MAIN_WINDOW_ID_3D );
2026-05-18 13:39:38 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isDockedInPlotView() const
{
return ( m_windowController != nullptr ) && ( m_windowController->mainWindowId() == RimDockWindowController::MAIN_WINDOW_ID_PLOTS );
2026-05-18 13:39:38 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::removeWindowFromDock()
{
if ( m_windowController != nullptr ) m_windowController->removeWindowFromDock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimViewWindow::windowTitle()
{
if ( userDescriptionField() )
{
caf::PdmUiFieldHandle* uiFieldHandle = userDescriptionField()->uiCapability();
if ( uiFieldHandle )
{
QVariant v = uiFieldHandle->uiValue();
return v.toString();
}
}
return QString( "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2026-05-12 17:46:29 +02:00
void RimViewWindow::deleteDockWidget()
{
if ( m_dockWidget && m_dockWidget->dockManager() )
{
m_dockWidget->dockManager()->removeDockWidget( m_dockWidget );
m_dockWidget->deleteLater();
m_dockWidget = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::updateDockWindowVisibility()
{
if ( !RiaGuiApplication::isRunning() ) return;
2019-05-06 10:36:05 +02:00
if ( m_windowController != nullptr )
{
m_windowController->setViewToControl( this );
m_windowController->updateViewerWidget();
}
else
{
if ( viewWidget() )
{
if ( isWindowVisible() )
{
viewWidget()->show();
}
else
{
viewWidget()->hide();
}
}
}
}
2019-11-15 10:12:19 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::dockAs3DViewWindow()
{
dockInWindow( RimDockWindowController::MAIN_WINDOW_ID_3D );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::dockAsPlotWindow()
{
dockInWindow( RimDockWindowController::MAIN_WINDOW_ID_PLOTS );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimViewWindow::snapshotWindowContent()
{
QImage image;
QWidget* widget = viewWidget();
if ( widget )
{
QPixmap pix = widget->grab();
image = pix.toImage();
}
return image;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::zoomAllAndReleaseUserDefinedRanges()
{
// Zoom All is an explicit request for automatic ranges, so release the user defined range of every axis owned by
// this window before zooming. Several plot types share RimPlotAxisProperties, so this is done for all of them.
for ( auto axisProperties : descendantsOfType<RimPlotAxisPropertiesInterface>() )
{
axisProperties->setRangeUserDefined( false );
}
zoomAll();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimViewWindow::captureSnapshot( int width, int height )
{
return internalCaptureSnapshot( m_dockWidget, viewWidget(), width, height );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimViewWindow::internalCaptureSnapshot( ads::CDockWidget* dockWidget, QWidget* widget, int width, int height )
{
if ( !widget ) return QImage();
if ( dockWidget && !dockWidget->isCurrentTab() )
{
// Move the dock widget that is stacked behind others in the same dock area to the top to make sure the snapshot is rendered
dockWidget->setAsCurrentTab();
QApplication::processEvents();
}
2026-06-09 01:12:48 +02:00
bool shouldResize = width > 0 && height > 0 && ( widget->width() != width || widget->height() != height );
2026-06-09 01:12:48 +02:00
QSize orgSize = widget->size();
if ( shouldResize )
{
widget->setFixedSize( width, height );
// setFixedSize() only posts a deferred resize. If the pending resize is delivered from inside QWidget::render() below, a child
// QScrollArea may move its viewport mid-render and crash in Qt's backing-store blit (QWidgetRepaintManager::bltRect).
QApplication::processEvents();
2026-06-09 01:12:48 +02:00
}
else
{
width = widget->width();
height = widget->height();
}
QPixmap pix( width, height );
pix.fill( Qt::transparent );
QPainter painter( &pix );
widget->render( &painter );
2026-06-09 01:12:48 +02:00
if ( shouldResize )
{
widget->setMinimumSize( 0, 0 );
widget->setMaximumSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
widget->resize( orgSize );
}
return pix.toImage();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::viewNavigationChanged()
{
onViewNavigationChanged();
}
//--------------------------------------------------------------------------------------------------
/// Default implementation of virtual method to trigger updates on view navigation (zoom, camera move, etc)
//--------------------------------------------------------------------------------------------------
void RimViewWindow::onViewNavigationChanged()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isWindowVisible() const
{
return m_showWindow();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimViewWindow::objectToggleField()
{
return &m_showWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2023-02-26 10:48:40 +01:00
void RimViewWindow::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField == &m_showWindow )
{
if ( isWindowVisible() )
{
onLoadDataAndUpdate();
2026-06-01 15:52:15 +02:00
setAsActiveViewer();
}
else
{
updateDockWindowVisibility();
}
uiCapability()->updateUiIconFromToggleField();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::updateWindowTitle()
{
updateWindowTitleIcon( windowTitle() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2026-08-19 16:57:00 +02:00
void RimViewWindow::updateWindowTitleIcon( QString title )
{
2026-05-05 00:10:08 +02:00
if ( viewWidget() && dockWidget() )
{
viewWidget()->setWindowTitle( title );
dockWidget()->setWindowTitle( title );
2026-06-01 15:52:15 +02:00
if ( isActiveViewer() )
2026-05-19 18:08:18 +02:00
{
dockWidget()->setIcon( QIcon( ":/ActiveWindow.svg" ) );
}
else
{
dockWidget()->setIcon( QIcon() );
}
}
}
2026-05-12 17:46:29 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimViewWindow::dockWindowName()
2026-05-12 17:46:29 +02:00
{
if ( m_dockWindowId().isEmpty() )
{
m_dockWindowId = RiuDockWidgetTools::uniqueIdForDockWidget();
}
return m_dockWindowId();
2026-05-12 17:46:29 +02:00
}
2026-06-02 17:29:04 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::resetDockWindowId()
{
m_dockWindowId = "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::dockInWindow( int mainWindowID )
{
if ( m_windowController == nullptr )
{
m_windowController = new RimDockWindowController();
}
m_windowController->setViewToControl( this );
m_windowController->setMainWindowId( mainWindowID );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
caf::PdmUiTreeViewItemAttribute* treeItemAttribute = dynamic_cast<caf::PdmUiTreeViewItemAttribute*>( attribute );
if ( treeItemAttribute && RiaPreferencesSystem::current()->showViewIdInProjectTree() && id() >= 0 )
{
treeItemAttribute->tags.clear();
2024-02-25 09:21:48 +01:00
auto tag = caf::PdmUiTreeViewItemAttribute::createTag();
2020-09-16 10:51:12 +02:00
tag->text = QString( "%1" ).arg( id() );
2019-11-14 20:48:11 +01:00
cvf::Color3f viewColor = RiaColorTables::contrastCategoryPaletteColors().cycledColor3f( (size_t)id() );
cvf::Color3f viewTextColor = RiaColorTools::contrastColor( viewColor );
2020-09-16 10:51:12 +02:00
tag->bgColor = QColor( RiaColorTools::toQColor( viewColor ) );
tag->fgColor = QColor( RiaColorTools::toQColor( viewTextColor ) );
treeItemAttribute->tags.push_back( std::move( tag ) );
}
}
2026-05-05 00:10:08 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2026-06-11 16:30:46 +02:00
ads::CDockWidget* RimViewWindow::dockWidget() const
2026-05-05 00:10:08 +02:00
{
return m_dockWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ads::CDockWidget* RimViewWindow::createDockWidget()
{
if ( !m_dockWidget )
{
m_dockWidget = new ads::CDockWidget( windowTitle() );
}
return m_dockWidget;
}
2026-05-19 02:26:59 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimViewWindow::setActive( bool active )
{
m_isActiveViewer = active;
2026-05-19 02:26:59 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isActiveViewer() const
2026-05-19 02:26:59 +02:00
{
return m_isActiveViewer;
2026-05-19 02:26:59 +02:00
}