mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-30 17:10:19 -05:00
#14459 Sort Z-scale factors and step through custom values with shortcuts
Introduce RiaZScaleTools as a single source for the Z-scale factor list, merging the predefined factors with custom values entered during the session. The toolbar combo box, the property editor combo box and the Ctrl+Shift+Up/Down shortcuts all use this shared sorted list. The toolbar combo box previously appended custom values at the end, producing an unsorted, ever-growing list, and the shortcuts stepped through the predefined factors only, skipping custom values visible in the list.
This commit is contained in:
1 parent
45a212d6c3
commit
15323a46cb
8 files changed
+259
-21
No files matched your search
@@ -61,6 +61,7 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaAngleUtils.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaAngleUtils.inl
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaToCafLogging.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaZScaleTools.h
|
||||
)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -116,6 +117,7 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaQuantityInfoTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaAngleUtils.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaToCafLogging.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaZScaleTools.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
|
||||
@@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 "RiaZScaleTools.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::set<double>& customScaleFactors()
|
||||
{
|
||||
static std::set<double> factors;
|
||||
return factors;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaZScaleTools::registerScaleFactor( double scaleFactor )
|
||||
{
|
||||
if ( scaleFactor <= 0.0 ) return;
|
||||
|
||||
customScaleFactors().insert( scaleFactor );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RiaZScaleTools::scaleFactorOptions()
|
||||
{
|
||||
std::set<double> options = customScaleFactors();
|
||||
|
||||
auto predefinedOptions = RiaDefines::viewScaleOptions();
|
||||
options.insert( predefinedOptions.begin(), predefinedOptions.end() );
|
||||
|
||||
return { options.begin(), options.end() };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RiaZScaleTools::nextScaleFactor( double currentScaleFactor, const std::vector<double>& sortedOptions )
|
||||
{
|
||||
auto it = std::upper_bound( sortedOptions.begin(), sortedOptions.end(), currentScaleFactor );
|
||||
if ( it == sortedOptions.end() ) return currentScaleFactor;
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RiaZScaleTools::previousScaleFactor( double currentScaleFactor, const std::vector<double>& sortedOptions )
|
||||
{
|
||||
auto it = std::lower_bound( sortedOptions.begin(), sortedOptions.end(), currentScaleFactor );
|
||||
if ( it == sortedOptions.begin() ) return currentScaleFactor;
|
||||
|
||||
return *( it - 1 );
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 <vector>
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
// Keeps track of the Z-scale factors available in the user interface: the predefined factors from
|
||||
// RiaDefines::viewScaleOptions() merged with any custom factors entered by the user during the
|
||||
// session. All consumers of the scale factor list (toolbar combo box, property editor combo box
|
||||
// and the increase/decrease keyboard shortcuts) use scaleFactorOptions() so they present and step
|
||||
// through the same sorted list.
|
||||
//
|
||||
//==================================================================================================
|
||||
class RiaZScaleTools
|
||||
{
|
||||
public:
|
||||
static void registerScaleFactor( double scaleFactor );
|
||||
static std::vector<double> scaleFactorOptions();
|
||||
|
||||
static double nextScaleFactor( double currentScaleFactor, const std::vector<double>& sortedOptions );
|
||||
static double previousScaleFactor( double currentScaleFactor, const std::vector<double>& sortedOptions );
|
||||
};
|
||||
@@ -19,14 +19,12 @@
|
||||
#include "RicZScaleFeatures.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaZScaleTools.h"
|
||||
|
||||
#include "Rim3dView.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
CAF_CMD_SOURCE_INIT( RicIncreaseZScaleFeature, "RicIncreaseZScaleFeature" );
|
||||
CAF_CMD_SOURCE_INIT( RicDecreaseZScaleFeature, "RicDecreaseZScaleFeature" );
|
||||
|
||||
@@ -56,12 +54,8 @@ void RicIncreaseZScaleFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
if ( Rim3dView* view = activeViewWithEditableZScale() )
|
||||
{
|
||||
auto scaleOptions = RiaDefines::viewScaleOptions();
|
||||
auto it = std::upper_bound( scaleOptions.begin(), scaleOptions.end(), view->scaleZ() );
|
||||
if ( it != scaleOptions.end() )
|
||||
{
|
||||
view->setScaleZAndUpdate( *it );
|
||||
}
|
||||
double nextScale = RiaZScaleTools::nextScaleFactor( view->scaleZ(), RiaZScaleTools::scaleFactorOptions() );
|
||||
view->setScaleZAndUpdate( nextScale );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +85,8 @@ void RicDecreaseZScaleFeature::onActionTriggered( bool isChecked )
|
||||
{
|
||||
if ( Rim3dView* view = activeViewWithEditableZScale() )
|
||||
{
|
||||
auto scaleOptions = RiaDefines::viewScaleOptions();
|
||||
auto it = std::lower_bound( scaleOptions.begin(), scaleOptions.end(), view->scaleZ() );
|
||||
if ( it != scaleOptions.begin() )
|
||||
{
|
||||
view->setScaleZAndUpdate( *( it - 1 ) );
|
||||
}
|
||||
double previousScale = RiaZScaleTools::previousScaleFactor( view->scaleZ(), RiaZScaleTools::scaleFactorOptions() );
|
||||
view->setScaleZAndUpdate( previousScale );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaPreferencesSystem.h"
|
||||
#include "RiaViewRedrawScheduler.h"
|
||||
#include "RiaZScaleTools.h"
|
||||
|
||||
#include "Rim2dIntersectionView.h"
|
||||
#include "Rim3dWellLogCurve.h"
|
||||
@@ -1016,6 +1017,8 @@ void Rim3dView::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const
|
||||
return;
|
||||
}
|
||||
|
||||
RiaZScaleTools::registerScaleFactor( m_scaleZ() );
|
||||
|
||||
updateScaling();
|
||||
|
||||
RiuMainWindow::instance()->updateScaleValue();
|
||||
@@ -1612,7 +1615,7 @@ QList<caf::PdmOptionItemInfo> Rim3dView::calculateValueOptions( const caf::PdmFi
|
||||
else if ( fieldNeedingOptions == &m_scaleZ )
|
||||
{
|
||||
// Include the current scale value in the options, as any value can be entered as text in the combo box
|
||||
auto scaleOptions = RiaDefines::viewScaleOptions();
|
||||
auto scaleOptions = RiaZScaleTools::scaleFactorOptions();
|
||||
if ( std::find( scaleOptions.begin(), scaleOptions.end(), m_scaleZ() ) == scaleOptions.end() )
|
||||
{
|
||||
scaleOptions.push_back( m_scaleZ() );
|
||||
|
||||
@@ -151,6 +151,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifSurfio-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifRmsWellPathReader-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaAngleUtils-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaZScaleTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicTransmissibilityCalculator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigCompletionDataGridCell-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/cafVecIjk-Test.cpp
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2026- 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 "gtest/gtest.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaZScaleTools.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaZScaleToolsTest, NextScaleFactor )
|
||||
{
|
||||
const std::vector<double> options = { 0.1, 0.5, 1.0, 5.0, 10.0 };
|
||||
|
||||
// Step from a predefined value
|
||||
EXPECT_DOUBLE_EQ( 5.0, RiaZScaleTools::nextScaleFactor( 1.0, options ) );
|
||||
|
||||
// Step from a custom value between two options
|
||||
EXPECT_DOUBLE_EQ( 5.0, RiaZScaleTools::nextScaleFactor( 3.0, options ) );
|
||||
|
||||
// Step from below the smallest option
|
||||
EXPECT_DOUBLE_EQ( 0.1, RiaZScaleTools::nextScaleFactor( 0.01, options ) );
|
||||
|
||||
// The largest option and values above it are unchanged
|
||||
EXPECT_DOUBLE_EQ( 10.0, RiaZScaleTools::nextScaleFactor( 10.0, options ) );
|
||||
EXPECT_DOUBLE_EQ( 100.0, RiaZScaleTools::nextScaleFactor( 100.0, options ) );
|
||||
|
||||
EXPECT_DOUBLE_EQ( 2.0, RiaZScaleTools::nextScaleFactor( 2.0, {} ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaZScaleToolsTest, PreviousScaleFactor )
|
||||
{
|
||||
const std::vector<double> options = { 0.1, 0.5, 1.0, 5.0, 10.0 };
|
||||
|
||||
// Step from a predefined value
|
||||
EXPECT_DOUBLE_EQ( 0.5, RiaZScaleTools::previousScaleFactor( 1.0, options ) );
|
||||
|
||||
// Step from a custom value between two options
|
||||
EXPECT_DOUBLE_EQ( 1.0, RiaZScaleTools::previousScaleFactor( 3.0, options ) );
|
||||
|
||||
// Step from above the largest option
|
||||
EXPECT_DOUBLE_EQ( 10.0, RiaZScaleTools::previousScaleFactor( 100.0, options ) );
|
||||
|
||||
// The smallest option and values below it are unchanged
|
||||
EXPECT_DOUBLE_EQ( 0.1, RiaZScaleTools::previousScaleFactor( 0.1, options ) );
|
||||
EXPECT_DOUBLE_EQ( 0.01, RiaZScaleTools::previousScaleFactor( 0.01, options ) );
|
||||
|
||||
EXPECT_DOUBLE_EQ( 2.0, RiaZScaleTools::previousScaleFactor( 2.0, {} ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaZScaleToolsTest, StepThroughCustomScaleFactorInBothDirections )
|
||||
{
|
||||
// A custom factor between two predefined values must be visited when stepping in both directions
|
||||
const std::vector<double> options = { 1.0, 5.0, 7.0, 10.0 };
|
||||
|
||||
EXPECT_DOUBLE_EQ( 7.0, RiaZScaleTools::nextScaleFactor( 5.0, options ) );
|
||||
EXPECT_DOUBLE_EQ( 10.0, RiaZScaleTools::nextScaleFactor( 7.0, options ) );
|
||||
EXPECT_DOUBLE_EQ( 7.0, RiaZScaleTools::previousScaleFactor( 10.0, options ) );
|
||||
EXPECT_DOUBLE_EQ( 5.0, RiaZScaleTools::previousScaleFactor( 7.0, options ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaZScaleToolsTest, ScaleFactorOptionsAreSortedAndUnique )
|
||||
{
|
||||
RiaZScaleTools::registerScaleFactor( 7.0 );
|
||||
RiaZScaleTools::registerScaleFactor( 7.0 );
|
||||
RiaZScaleTools::registerScaleFactor( 0.3 );
|
||||
|
||||
// Registering a predefined value or an invalid value must not create duplicates or new entries
|
||||
RiaZScaleTools::registerScaleFactor( 1.0 );
|
||||
RiaZScaleTools::registerScaleFactor( 0.0 );
|
||||
RiaZScaleTools::registerScaleFactor( -2.0 );
|
||||
|
||||
auto options = RiaZScaleTools::scaleFactorOptions();
|
||||
|
||||
EXPECT_TRUE( std::is_sorted( options.begin(), options.end() ) );
|
||||
EXPECT_EQ( options.end(), std::adjacent_find( options.begin(), options.end() ) );
|
||||
|
||||
EXPECT_NE( options.end(), std::find( options.begin(), options.end(), 7.0 ) );
|
||||
EXPECT_NE( options.end(), std::find( options.begin(), options.end(), 0.3 ) );
|
||||
EXPECT_EQ( options.end(), std::find( options.begin(), options.end(), 0.0 ) );
|
||||
EXPECT_EQ( options.end(), std::find( options.begin(), options.end(), -2.0 ) );
|
||||
|
||||
// All predefined values must be present
|
||||
for ( auto predefined : RiaDefines::viewScaleOptions() )
|
||||
{
|
||||
EXPECT_NE( options.end(), std::find( options.begin(), options.end(), predefined ) );
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "RiaPreferencesSystem.h"
|
||||
#include "RiaRegressionTest.h"
|
||||
#include "RiaRegressionTestRunner.h"
|
||||
#include "RiaZScaleTools.h"
|
||||
|
||||
#include "RicGridCalculatorDialog.h"
|
||||
|
||||
@@ -670,8 +671,7 @@ void RiuMainWindow::createToolBars()
|
||||
toolbar->addWidget( scaleLabel );
|
||||
|
||||
m_scaleFactor = new QComboBox( toolbar );
|
||||
QStringList scaleItems;
|
||||
for ( auto d : RiaDefines::viewScaleOptions() )
|
||||
for ( auto d : RiaZScaleTools::scaleFactorOptions() )
|
||||
{
|
||||
m_scaleFactor->addItem( QString::number( d ), QVariant( d ) );
|
||||
}
|
||||
@@ -1928,13 +1928,22 @@ void RiuMainWindow::updateScaleValue()
|
||||
m_scaleFactor->setEnabled( true );
|
||||
m_scaleFactor->blockSignals( true );
|
||||
|
||||
// Register the scale of the view to make custom values from project files available, and rebuild
|
||||
// the item list to keep it sorted as the set of scale factors grows during the session
|
||||
RiaZScaleTools::registerScaleFactor( view->scaleZ() );
|
||||
|
||||
m_scaleFactor->clear();
|
||||
for ( auto scale : RiaZScaleTools::scaleFactorOptions() )
|
||||
{
|
||||
m_scaleFactor->addItem( QString::number( scale ), QVariant( scale ) );
|
||||
}
|
||||
int index = m_scaleFactor->findData( QVariant( view->scaleZ() ) );
|
||||
m_scaleFactor->setCurrentIndex( index );
|
||||
if ( index < 0 )
|
||||
{
|
||||
m_scaleFactor->addItem( QString::number( view->scaleZ() ), QVariant( view->scaleZ() ) );
|
||||
index = m_scaleFactor->findData( QVariant( view->scaleZ() ) );
|
||||
// A non-positive scale from a project file is not registered as an option, display it as text
|
||||
m_scaleFactor->setEditText( QString::number( view->scaleZ() ) );
|
||||
}
|
||||
m_scaleFactor->setCurrentIndex( index );
|
||||
|
||||
m_scaleFactor->blockSignals( false );
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user