Skip to content

Commit

Permalink
Add static function to define a subset of enums to be used for AppEnum
Browse files Browse the repository at this point in the history
Add a static map between field keyword and a subset of enum values to be displayed in the GUI
If a subset is defined, automatically calculate value options for this subset, otherwise, use all enums
Improve the macro so it is possible to use the `EnumType` instead of `AppEnum<EnumType>` when defining the default value
  • Loading branch information
magnesj authored Feb 8, 2025
1 parent 72f898a commit 7e523e3
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 28 deletions.
5 changes: 4 additions & 1 deletion Fwk/AppFwk/cafPdmCvf/cafPdmMat3d/cafPdmUiCoreMat3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class PdmUiFieldSpecialization<cvf::Mat3d>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const cvf::Mat3d& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Mat3d& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<cvf::Mat3d>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down
5 changes: 4 additions & 1 deletion Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class PdmUiFieldSpecialization<cvf::Color3f>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const cvf::Color3f& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Color3f& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<cvf::Color3f>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down
5 changes: 4 additions & 1 deletion Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreMat4d.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class PdmUiFieldSpecialization<cvf::Mat4d>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const cvf::Mat4d& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Mat4d& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<cvf::Mat4d>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down
5 changes: 4 additions & 1 deletion Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ class PdmUiFieldSpecialization<cvf::Vec3d>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const cvf::Vec3d& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const cvf::Vec3d& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<cvf::Vec3d>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down
25 changes: 25 additions & 0 deletions Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAppEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <QString>
#include <QStringList>

#include <map>
#include <vector>

namespace caf
Expand Down Expand Up @@ -95,6 +96,16 @@ namespace caf
/// options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<TestEnumType>::uiTextFromIndex(i),
/// caf::AppEnum<TestEnumType>::fromIndex(i)));
/// }
///
/// Subset of enums:
///
/// Define a subset of the enum to be used in a field. Assign a value from the subset to make sure the field
/// contains a valid value when the constructor is done.
///
/// CAF_PDM_InitField( &m_enum2Field, "Enum2Field", MyEnumType::T6, "Subset using setEnumSubset()" );
/// caf::AppEnum<MyEnumType>::setEnumSubset( m_enum2Field.keyword(), { MyEnumType::T2, MyEnumType::T6 } );
///
///
//==================================================================================================

class AppEnumInterface
Expand All @@ -117,6 +128,15 @@ class AppEnum : public AppEnumInterface
{
}

static void setEnumSubset( QString fieldKeyword, std::vector<T> subset ) { m_enumSubset[fieldKeyword] = subset; }
static std::vector<T> enumSubset( QString fieldKeyword )
{
auto it = m_enumSubset.find( fieldKeyword );
if ( it != m_enumSubset.end() ) return it->second;

return {};
}

operator T() const { return m_value; }

T value() const { return m_value; }
Expand Down Expand Up @@ -176,6 +196,8 @@ class AppEnum : public AppEnumInterface

T m_value;

static std::map<QString, std::vector<T>> m_enumSubset;

//==================================================================================================
/// A private class to handle the instance of the mapping vector.
/// all access methods could have been placed directly in the \class AppEnum class,
Expand Down Expand Up @@ -354,4 +376,7 @@ class AppEnum : public AppEnumInterface
};
};

template <class T>
std::map<QString, std::vector<T>> AppEnum<T>::m_enumSubset;

} // namespace caf
43 changes: 30 additions & 13 deletions Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmU
PdmObject();
~PdmObject() override {}

/// Returns _this_ if _this_ has requested class keyword
/// Traverses parents recursively and returns first parent of the requested
/// type.
void firstAncestorOrThisFromClassKeyword( const QString& classKeyword, PdmObject*& ancestor ) const;

/// Traverses all children recursively to find objects of the requested
/// class keyword. This object is also
/// included if it has the requested class keyword
void descendantsIncludingThisFromClassKeyword( const QString& classKeyword, std::vector<PdmObject*>& descendants ) const;

/// Gets all children matching class keyword. Not recursive.
void childrenFromClassKeyword( const QString& classKeyword, std::vector<PdmObject*>& children ) const;

/// Adds field to the internal data structure and sets the file keyword and Ui information
/// Consider this method private. Please use the CAF_PDM_InitField() macro instead
template <typename FieldDataType>
Expand All @@ -170,23 +183,27 @@ class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmU
*field = defaultValue;
}

/// Template specialization for AppEnum to make it possible to use an enum value as the default value.
///
/// In the header file:
/// caf::PdmField<caf::AppEnum<MyEnumType>> m_enum2Field;
/// In the source file:
/// CAF_PDM_InitField( &m_enum2Field, "m_enum2Field", MyEnumType::T6, "Subset using setEnumSubset()" );
///
template <typename FieldDataType>
void addFieldUi( PdmField<AppEnum<FieldDataType>>* field,
const QString& keyword,
const FieldDataType& defaultValue,
PdmUiItemInfo* fieldDescription )
{
auto defaultAppEnum = AppEnum<FieldDataType>( defaultValue );
addFieldUi( field, keyword, defaultAppEnum, fieldDescription );
}

/// Does the same as the above method, but omits the default value.
/// Consider this method private. Please use the CAF_PDM_InitFieldNoDefault() macro instead.
void addFieldUiNoDefault( PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo* fieldDescription );

/// Returns _this_ if _this_ has requested class keyword
/// Traverses parents recursively and returns first parent of the requested
/// type.
void firstAncestorOrThisFromClassKeyword( const QString& classKeyword, PdmObject*& ancestor ) const;

/// Traverses all children recursively to find objects of the requested
/// class keyword. This object is also
/// included if it has the requested class keyword
void descendantsIncludingThisFromClassKeyword( const QString& classKeyword, std::vector<PdmObject*>& descendants ) const;

/// Gets all children matching class keyword. Not recursive.
void childrenFromClassKeyword( const QString& classKeyword, std::vector<PdmObject*>& children ) const;

protected:
PdmObjectHandle* doCopyObject() const override;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ class PdmUiFieldSpecialization<PdmPointer<T>>
return variantValue.value<PdmPointer<PdmObjectHandle>>() == variantValue2.value<PdmPointer<PdmObjectHandle>>();
}

static QList<PdmOptionItemInfo> valueOptions( const PdmPointer<T>& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const PdmPointer<T>& )
{
return QList<PdmOptionItemInfo>();
}
};

//==================================================================================================
Expand Down Expand Up @@ -87,7 +90,10 @@ class PdmUiFieldSpecialization<std::list<T>>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const std::list<T>& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::list<T>& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<std::list<T>>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down Expand Up @@ -120,7 +126,10 @@ class PdmUiFieldSpecialization<std::vector<T>>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const std::vector<T>& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::vector<T>& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<std::vector<T>>& field, std::vector<PdmObjectHandle*>* objects )
Expand Down Expand Up @@ -156,14 +165,23 @@ class PdmUiFieldSpecialization<caf::AppEnum<T>>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const caf::AppEnum<T>& )
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const caf::AppEnum<T>& appEnum )
{
QList<PdmOptionItemInfo> optionList;

for ( size_t i = 0; i < caf::AppEnum<T>::size(); ++i )
// If a subset of the enum is defined, use that subset
auto enumValues = caf::AppEnum<T>::enumSubset( keyword );
if ( enumValues.empty() )
{
T enumVal = caf::AppEnum<T>::fromIndex( i );
optionList.push_back( PdmOptionItemInfo( caf::AppEnum<T>::uiTextFromIndex( i ), static_cast<int>( enumVal ) ) );
// If no subset is defined, use all values
for ( size_t i = 0; i < caf::AppEnum<T>::size(); ++i )
{
enumValues.push_back( caf::AppEnum<T>::fromIndex( i ) );
}
}
for ( auto enumValue : enumValues )
{
optionList.push_back( PdmOptionItemInfo( caf::AppEnum<T>::uiText( enumValue ), static_cast<int>( enumValue ) ) );
}

return optionList;
Expand Down Expand Up @@ -197,7 +215,7 @@ class PdmUiFieldSpecialization<std::pair<T, U>>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const std::pair<T, U>& )
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const std::pair<T, U>& )
{
QList<PdmOptionItemInfo> optionList;

Expand Down Expand Up @@ -236,7 +254,10 @@ class PdmUiFieldSpecialization<caf::FilePath>
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const caf::FilePath& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const caf::FilePath& )
{
return QList<PdmOptionItemInfo>();
}

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<caf::FilePath>& field, std::vector<PdmObjectHandle*>* objects ) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ QList<PdmOptionItemInfo> PdmFieldUiCap<FieldType>::valueOptions() const

if ( m_optionEntryCache.empty() )
{
m_optionEntryCache = PdmUiFieldSpecialization<typename FieldType::FieldDataType>::valueOptions( m_field->value() );
auto keyword = m_field->keyword();
m_optionEntryCache =
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::valueOptions( keyword, m_field->value() );
}

if ( !m_optionEntryCache.empty() && isAutoAddingOptionFromValue() )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class PdmUiFieldSpecialization
}

/// Methods to get a list of options for a field, specialized for AppEnum
static QList<PdmOptionItemInfo> valueOptions( const T& ) { return QList<PdmOptionItemInfo>(); }
static QList<PdmOptionItemInfo> valueOptions( QString keyword, const T& ) { return QList<PdmOptionItemInfo>(); }

/// Methods to retrieve the possible PdmObject pointed to by a field
static void childObjects( const PdmDataValueField<T>&, std::vector<PdmObjectHandle*>* ) {}
Expand Down
62 changes: 62 additions & 0 deletions Fwk/AppFwk/cafTests/cafTestApplication/ApplicationEnum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#include "ApplicationEnum.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"

template <>
void caf::AppEnum<ApplicationEnum::MyEnumType>::setUp()
{
addItem( ApplicationEnum::MyEnumType::T1, "T1", "T 1" );
addItem( ApplicationEnum::MyEnumType::T2, "T2", "T 2" );
addItem( ApplicationEnum::MyEnumType::T3, "T3", "T 3" );
addItem( ApplicationEnum::MyEnumType::T4, "T4", "T 4" );
addItem( ApplicationEnum::MyEnumType::T5, "T5", "T 5" );
addItem( ApplicationEnum::MyEnumType::T6, "T5", "T 6" );
addItem( ApplicationEnum::MyEnumType::T7, "T6", "T 7" );

setDefault( ApplicationEnum::MyEnumType::T4 );
}

CAF_PDM_SOURCE_INIT( ApplicationEnum, "ApplicationEnum" );

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ApplicationEnum::ApplicationEnum()
{
CAF_PDM_InitObject( "Application Enum", "", "", "" );

// Enum field displaying all defined enums
CAF_PDM_InitFieldNoDefault( &m_enumField, "EnumField", "All Enums" );

// Enum field displaying a subset of the defined enums using the static function setEnumSubset()
CAF_PDM_InitField( &m_enum2Field, "Enum2Field", MyEnumType::T6, "Subset using setEnumSubset()" );
caf::AppEnum<MyEnumType>::setEnumSubset( m_enum2Field.keyword(), { MyEnumType::T2, MyEnumType::T6 } );

// Enum field displaying a subset of the defined enums using calculateValueOptions()
CAF_PDM_InitFieldNoDefault( &m_enum3Field, "Enum3Field", "Subset using calculateValueOptions()" );
m_enum3Field = MyEnumType::T2;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> ApplicationEnum::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
if ( fieldNeedingOptions == &m_enum3Field )
{
QList<caf::PdmOptionItemInfo> options;

options.push_back(
caf::PdmOptionItemInfo( caf::AppEnum<ApplicationEnum::MyEnumType>::uiText( ApplicationEnum::MyEnumType::T2 ),
ApplicationEnum::MyEnumType::T2 ) );

options.push_back(
caf::PdmOptionItemInfo( caf::AppEnum<ApplicationEnum::MyEnumType>::uiText( ApplicationEnum::MyEnumType::T3 ),
ApplicationEnum::MyEnumType::T3 ) );

return options;
}

return {};
}
32 changes: 32 additions & 0 deletions Fwk/AppFwk/cafTests/cafTestApplication/ApplicationEnum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "cafPdmField.h"
#include "cafPdmObject.h"

class ApplicationEnum : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;

public:
enum class MyEnumType
{
T1,
T2,
T3,
T4,
T5,
T6,
T7
};

public:
ApplicationEnum();

private:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;

private:
caf::PdmField<caf::AppEnum<MyEnumType>> m_enumField;
caf::PdmField<caf::AppEnum<MyEnumType>> m_enum2Field;
caf::PdmField<caf::AppEnum<MyEnumType>> m_enum3Field;
};
2 changes: 2 additions & 0 deletions Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ set(PROJECT_FILES
TamComboBox.cpp
LineEditAndPushButtons.h
LineEditAndPushButtons.cpp
ApplicationEnum.h
ApplicationEnum.cpp
)

qt_add_executable(
Expand Down
3 changes: 3 additions & 0 deletions Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "MainWindow.h"

#include "ApplicationEnum.h"
#include "CustomObjectEditor.h"
#include "LineEditAndPushButtons.h"
#include "ManyGroups.h"
Expand Down Expand Up @@ -1332,6 +1333,8 @@ void MainWindow::buildTestModel()
demoObj2->m_objectList.push_back( new SmallDemoPdmObject() );

delete smallObj3;

m_testRoot->objects.push_back( new ApplicationEnum );
}

//--------------------------------------------------------------------------------------------------
Expand Down

0 comments on commit 7e523e3

Please sign in to comment.