From 98ea83146afa31075a605d0087a48d606bc29f4c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 4 Jun 2026 17:00:41 +0200 Subject: [PATCH] #14122 Allow tree selection editor to grow only when it is the last row The tree selection editor can grow to a large height, which is useful when it is the last field editor in the property dialog. When other field editors are located below, the heightHint is now used as the maximum height instead. The form layout tracks whether an editor occupies the bottom-most row of the form and passes this to the editor. In the Analysis Plot, the time step selection is constrained to its height hint because other input fields are located below it. --- .../AnalysisPlots/RimAnalysisPlot.cpp | 14 +++++++++++ .../AnalysisPlots/RimAnalysisPlot.h | 1 + .../cafPdmUiFieldEditorHandle.cpp | 16 +++++++++++++ .../cafPdmUiCore/cafPdmUiFieldEditorHandle.h | 6 +++++ .../cafPdmUiFormLayoutObjectEditor.cpp | 23 ++++++++++++++----- .../cafPdmUiFormLayoutObjectEditor.h | 9 +++++--- .../cafPdmUiTreeSelectionEditor.cpp | 17 ++++++++++++++ 7 files changed, 77 insertions(+), 9 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp b/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp index 039a80febb..dad8f3dda8 100644 --- a/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp @@ -692,6 +692,20 @@ QList RimAnalysisPlot::calculateValueOptions( const caf: return options; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimAnalysisPlot::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) +{ + if ( field == &m_selectedTimeSteps ) + { + if ( auto* attrib = dynamic_cast( attribute ) ) + { + attrib->heightHint = 150; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h b/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h index e9e037a4ff..81263d9f99 100644 --- a/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h +++ b/ApplicationLibCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.h @@ -105,6 +105,7 @@ private: caf::PdmFieldHandle* userDescriptionField() override; QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; + void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; std::set allAvailableTimeSteps() const; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp index 62ee7f4757..064545f5a4 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp @@ -182,6 +182,22 @@ int PdmUiFieldEditorHandle::rowStretchFactor() const return isMultiRowEditor() ? 1 : 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiFieldEditorHandle::setIsInLastFormRow( bool isLast ) +{ + m_isInLastFormRow = isLast; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiFieldEditorHandle::isInLastFormRow() const +{ + return m_isInLastFormRow; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h index debcf25fc7..84623b7899 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h @@ -102,6 +102,11 @@ public: QMargins labelContentMargins() const; int rowStretchFactor() const; + /// True if this editor occupies the bottom-most row of the entire form. Editors that can grow + /// vertically may use this to fill the remaining space instead of being constrained to a height hint. + void setIsInLastFormRow( bool isLast ); + bool isInLastFormRow() const; + void updateValidationState(); protected: // Virtual interface to override @@ -132,6 +137,7 @@ private: QPointer m_editorWidget; QPointer m_labelWidget; QPointer m_validationErrorAction; + bool m_isInLastFormRow = true; }; //================================================================================================== diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp index 13dc1de88c..4ee35adcb4 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp @@ -88,12 +88,14 @@ caf::PdmUiFormLayoutObjectEditor::~PdmUiFormLayoutObjectEditor() //-------------------------------------------------------------------------------------------------- bool caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInNewGridLayout( const PdmUiOrdering& uiOrdering, QWidget* containerWidget, - const QString& uiConfigName ) + const QString& uiConfigName, + bool parentRowIsLast ) { QSize beforeSize = containerWidget->sizeHint(); ensureWidgetContainsEmptyGridLayout( containerWidget ); - int stretch = recursivelyConfigureAndUpdateUiOrderingInGridLayout( uiOrdering, containerWidget, uiConfigName ); + int stretch = + recursivelyConfigureAndUpdateUiOrderingInGridLayout( uiOrdering, containerWidget, uiConfigName, parentRowIsLast ); QSize afterSize = containerWidget->sizeHint(); if ( beforeSize != afterSize ) @@ -110,7 +112,8 @@ bool caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingIn //-------------------------------------------------------------------------------------------------- int caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInGridLayout( const PdmUiOrdering& uiOrdering, QWidget* containerWidgetWithGridLayout, - const QString& uiConfigName ) + const QString& uiConfigName, + bool parentRowIsLast ) { int sumRowStretch = 0; CAF_ASSERT( containerWidgetWithGridLayout ); @@ -130,6 +133,10 @@ int caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInG { int currentColumn = 0; + // True when this row is the bottom-most row of the entire form. Editors that can grow vertically + // use this to fill the remaining space rather than being constrained to a fixed height hint. + bool rowIsLast = parentRowIsLast && ( currentRowIndex == totalRows - 1 ); + const PdmUiOrdering::RowLayout& uiItemsInRow = tableLayout[currentRowIndex]; int columnsRequiredForCurrentRow = uiOrdering.nrOfRequiredColumnsInRow( uiItemsInRow ); @@ -171,7 +178,8 @@ int caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInG parentLayout, currentRowIndex, currentColumn, - itemColumnSpan ); + itemColumnSpan, + rowIsLast ); parentLayout->setRowStretch( currentRowIndex, groupStretchFactor ); currentColumn += itemColumnSpan; sumRowStretch += groupStretchFactor; @@ -313,6 +321,7 @@ int caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInG parentLayout->setRowStretch( currentRowIndex, fieldEditor->rowStretchFactor() ); sumRowStretch += fieldEditor->rowStretchFactor(); } + fieldEditor->setIsInLastFormRow( rowIsLast ); fieldEditor->updateUi( uiConfigName ); } } @@ -334,13 +343,15 @@ int caf::PdmUiFormLayoutObjectEditor::recursivelyAddGroupToGridLayout( PdmUiItem QGridLayout* parentLayout, int currentRowIndex, int currentColumn, - int itemColumnSpan ) + int itemColumnSpan, + bool parentRowIsLast ) { PdmUiGroup* group = static_cast( currentItem ); QMinimizePanel* groupBox = findOrCreateGroupBox( containerWidgetWithGridLayout, group, uiConfigName ); - int stretch = recursivelyConfigureAndUpdateUiOrderingInGridLayout( *group, groupBox->contentFrame(), uiConfigName ); + int stretch = + recursivelyConfigureAndUpdateUiOrderingInGridLayout( *group, groupBox->contentFrame(), uiConfigName, parentRowIsLast ); /// Insert the group box at the correct position of the parent layout parentLayout->addWidget( groupBox, currentRowIndex, currentColumn, 1, itemColumnSpan ); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h index 78ad8a6ae3..dfe8869ece 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h @@ -79,10 +79,12 @@ protected: bool recursivelyConfigureAndUpdateUiOrderingInNewGridLayout( const PdmUiOrdering& uiOrdering, QWidget* containerWidget, - const QString& uiConfigName ); + const QString& uiConfigName, + bool parentRowIsLast = true ); int recursivelyConfigureAndUpdateUiOrderingInGridLayout( const PdmUiOrdering& uiOrdering, QWidget* containerWidgetWithGridLayout, - const QString& uiConfigName ); + const QString& uiConfigName, + bool parentRowIsLast = true ); int recursivelyAddGroupToGridLayout( PdmUiItem* currentItem, QWidget* containerWidget, @@ -90,7 +92,8 @@ protected: QGridLayout* parentLayout, int currentRowIndex, int currentColumn, - int itemColumnSpan ); + int itemColumnSpan, + bool parentRowIsLast = true ); QMinimizePanel* findOrCreateGroupBox( QWidget* parent, PdmUiGroup* group, const QString& uiConfigName ); PdmUiFieldEditorHandle* findOrCreateFieldEditor( QWidget* parent, PdmUiFieldHandle* field, const QString& uiConfigName ); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp index 94c8caa6ed..d56bfc2ac2 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp @@ -309,6 +309,23 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi( const QString& uiConfigName if ( m_attributes.heightHint > 0 ) { m_treeView->setHeightHint( m_attributes.heightHint ); + + // The tree selection editor is a multi-row editor, so its row is given a stretch factor in the + // property layout. Without an upper bound the tree view would expand to fill all available vertical + // space, ignoring the height hint. Cap the height so the hint is respected - unless this editor is + // the bottom-most widget in the form, in which case let it grow to fill the remaining space. + if ( isInLastFormRow() ) + { + m_treeView->setMaximumHeight( QWIDGETSIZE_MAX ); + } + else + { + m_treeView->setMaximumHeight( m_attributes.heightHint ); + } + } + else + { + m_treeView->setMaximumHeight( QWIDGETSIZE_MAX ); } // If the tree doesn't have grand children we treat this as a straight list