diff --git a/common/properties/property_mgr.cpp b/common/properties/property_mgr.cpp index 66588bee2a..9bd37b86ed 100644 --- a/common/properties/property_mgr.cpp +++ b/common/properties/property_mgr.cpp @@ -194,6 +194,36 @@ void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aN } +void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, + const wxString& aName, + std::function aFunc ) +{ + wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" ); + + CLASS_DESC& derived = getClass( aDerived ); + derived.m_availabilityOverrides[std::make_pair( aBase, aName )] = aFunc; + m_dirty = true; +} + + +bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, + INSPECTABLE* aItem ) +{ + if( !aProp->Available( aItem ) ) + return false; + + CLASS_DESC& derived = getClass( aItemClass ); + + auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(), + aProp->Name() ) ); + + if( it != derived.m_availabilityOverrides.end() ) + return it->second( aItem ); + + return true; +} + + bool PROPERTY_MANAGER::IsOfType( TYPE_ID aDerived, TYPE_ID aBase ) const { if( aDerived == aBase ) diff --git a/common/widgets/properties_panel.cpp b/common/widgets/properties_panel.cpp index 054c316c2d..21a90204f5 100644 --- a/common/widgets/properties_panel.cpp +++ b/common/widgets/properties_panel.cpp @@ -194,7 +194,8 @@ void PROPERTIES_PANEL::update( const SELECTION& aSelection ) if( property->IsInternal() ) continue; - if( !property->Available( aSelection.Front() ) ) + if( !propMgr.IsAvailableFor( TYPE_HASH( *aSelection.Front() ), property, + aSelection.Front() ) ) continue; // Either determine the common value for a property or "<...>" to indicate multiple values @@ -203,7 +204,7 @@ void PROPERTIES_PANEL::update( const SELECTION& aSelection ) for( EDA_ITEM* item : aSelection ) { - if( !property->Available( item ) ) + if( !propMgr.IsAvailableFor( TYPE_HASH( *item ), property, item ) ) break; // there is an item that does not have this property, so do not display it wxVariant& value = commonVal.IsNull() ? commonVal : itemVal; diff --git a/include/properties/property_mgr.h b/include/properties/property_mgr.h index 9fd4931956..373e280470 100644 --- a/include/properties/property_mgr.h +++ b/include/properties/property_mgr.h @@ -39,6 +39,7 @@ class PROPERTY_BASE; class TYPE_CAST_BASE; class ORIGIN_TRANSFORMS; +class INSPECTABLE; ///< Unique type identifier using TYPE_ID = size_t; @@ -47,6 +48,11 @@ using PROPERTY_LIST = std::vector; using PROPERTY_SET = std::set>; +template +using PROPERTY_MAP = std::map, ValueType>; + +using PROPERTY_FUNCTOR_MAP = PROPERTY_MAP>; + using PROPERTY_DISPLAY_ORDER = std::map; /** @@ -173,12 +179,32 @@ public: /** * Sets a base class property as masked in a derived class. Masked properties are hidden from * the list of editable properties for this class. + * * @param aDerived is the type to apply the mask for. * @param aBase is the type that aName belongs to. - * @param aName is the name of a property. + * @param aName is the name of a property on the base class. */ void Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName ); + /** + * Sets an override availability functor for a base class property of a given derived class. + * + * @param aDerived is the type to apply the mask for. + * @param aBase is the type that aName belongs to. + * @param aName is the name of a property on the base class. + * @param aFunc is the new availability functor to apply. + */ + void OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName, + std::function aFunc ); + + /** + * Checks overriden availability and original availability of a property, returns false + * if the property is unavailable in either case. + * + * TODO: This isn't the cleanest API, consider how to merge with PROPERTY_BASE::Available + */ + bool IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem ); + /** * Return true if aDerived is inherited from aBase. */ @@ -249,6 +275,9 @@ private: ///< Properties from bases that should be masked (hidden) on this subclass PROPERTY_SET m_maskedBaseProperties; + ///< Overrides for base class property availabilities + PROPERTY_FUNCTOR_MAP m_availabilityOverrides; + ///< All properties (both unique to the type and inherited) std::vector m_allProperties; diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index dd6f143b4c..0f9cd45aaa 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -1401,6 +1401,11 @@ static struct ZONE_DESC layer->SetIsInternal( true ); propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layer ); + propMgr.OverrideAvailability( TYPE_HASH( ZONE ), TYPE_HASH( BOARD_CONNECTED_ITEM ), + _HKI( "Net" ), isCopperZone ); + propMgr.OverrideAvailability( TYPE_HASH( ZONE ), TYPE_HASH( BOARD_CONNECTED_ITEM ), + _HKI( "Net Class" ), isCopperZone ); + auto priority = new PROPERTY( _HKI( "Priority" ), &ZONE::SetAssignedPriority, &ZONE::GetAssignedPriority ); priority->SetAvailableFunc( isCopperZone );