From 77c19fa99a8ea76a878a135f0c4f76033780a62b Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 4 Feb 2024 23:01:16 +0000 Subject: [PATCH] Fill in missing zone properties. Also fixes some bugs with hatch properties being available on rule areas. --- common/properties/pg_editors.cpp | 19 +++++ common/properties/pg_properties.cpp | 47 ++++++++++-- include/properties/pg_properties.h | 21 +++++- include/properties/property.h | 1 + pcbnew/zone.cpp | 112 ++++++++++++++++++++-------- pcbnew/zone.h | 1 + 6 files changed, 160 insertions(+), 41 deletions(-) diff --git a/common/properties/pg_editors.cpp b/common/properties/pg_editors.cpp index 910fe0301e..5c1cad847f 100644 --- a/common/properties/pg_editors.cpp +++ b/common/properties/pg_editors.cpp @@ -88,6 +88,10 @@ wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGPr { m_unitBinder->SetCoordType( prop->CoordType() ); } + else if( dynamic_cast( aProperty) != nullptr ) + { + m_unitBinder->SetDataType( EDA_DATA_TYPE::AREA ); + } else if( dynamic_cast( aProperty ) != nullptr ) { m_unitBinder->SetCoordType( ORIGIN_TRANSFORMS::NOT_A_COORD ); @@ -108,6 +112,10 @@ void PG_UNIT_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) c { m_unitBinder->ChangeValue( var.GetLong() ); } + else if( var.GetType() == wxPG_VARIANT_TYPE_LONGLONG ) + { + m_unitBinder->ChangeDoubleValue( var.GetLongLong().ToDouble() ); + } else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE ) { m_unitBinder->ChangeValue( var.GetDouble() ); @@ -186,6 +194,17 @@ bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aPr } } } + else if( dynamic_cast( aProperty ) != nullptr ) + { + wxLongLongNative result = m_unitBinder->GetValue(); + changed = ( aVariant.IsNull() || result != aVariant.GetLongLong() ); + + if( changed ) + { + aVariant = result; + m_unitBinder->SetDoubleValue( result.ToDouble() ); + } + } else { long result = m_unitBinder->GetValue(); diff --git a/common/properties/pg_properties.cpp b/common/properties/pg_properties.cpp index d2dd82ac35..70d2a4111c 100644 --- a/common/properties/pg_properties.cpp +++ b/common/properties/pg_properties.cpp @@ -35,10 +35,6 @@ #include #include -// reg-ex describing a signed valid value with a unit -static const wxChar REGEX_SIGNED_DISTANCE[] = wxT( "([-+]?[0-9]+[\\.?[0-9]*) *(mm|in|mils)*" ); -static const wxChar REGEX_UNSIGNED_DISTANCE[] = wxT( "([0-9]+[\\.?[0-9]*) *(mm|in|mils)*" ); - class wxAnyToEDA_ANGLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration { @@ -127,6 +123,11 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) ); break; + case PROPERTY_DISPLAY::PT_AREA: + ret = new PGPROPERTY_AREA( aFrame ); + ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) ); + break; + case PROPERTY_DISPLAY::PT_COORD: ret = new PGPROPERTY_COORD( aFrame, aProperty->CoordType() ); ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) ); @@ -208,12 +209,11 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* } -PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( EDA_DRAW_FRAME* aParentFrame, const wxString& aRegEx, +PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( EDA_DRAW_FRAME* aParentFrame, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ) : m_parentFrame( aParentFrame ), m_coordType( aCoordType ) { - m_regExValidator.reset( new REGEX_VALIDATOR( aRegEx ) ); } @@ -265,9 +265,40 @@ wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFla } +PGPROPERTY_AREA::PGPROPERTY_AREA( EDA_DRAW_FRAME* aParentFrame ) : + wxIntProperty( wxPG_LABEL, wxPG_LABEL, 0 ), + m_parentFrame( aParentFrame ) +{ +} + + +bool PGPROPERTY_AREA::StringToValue( wxVariant& aVariant, const wxString& aText, + int aArgFlags ) const +{ + // TODO(JE): Are there actual use cases for this? + wxCHECK_MSG( false, false, wxS( "PGPROPERTY_AREA::StringToValue should not be used." ) ); +} + + +wxString PGPROPERTY_AREA::ValueToString( wxVariant& aVariant, int aArgFlags ) const +{ + wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONGLONG, wxEmptyString ); + + wxLongLongNative areaIU = aVariant.GetLongLong(); + + return m_parentFrame->StringFromValue( areaIU.ToDouble(), true, EDA_DATA_TYPE::AREA ); +} + + +wxValidator* PGPROPERTY_AREA::DoGetValidator() const +{ + return nullptr; +} + + PGPROPERTY_SIZE::PGPROPERTY_SIZE( EDA_DRAW_FRAME* aParentFrame ) : wxUIntProperty( wxPG_LABEL, wxPG_LABEL, 0 ), - PGPROPERTY_DISTANCE( aParentFrame, REGEX_UNSIGNED_DISTANCE, ORIGIN_TRANSFORMS::NOT_A_COORD ) + PGPROPERTY_DISTANCE( aParentFrame, ORIGIN_TRANSFORMS::NOT_A_COORD ) { } @@ -281,7 +312,7 @@ wxValidator* PGPROPERTY_SIZE::DoGetValidator() const PGPROPERTY_COORD::PGPROPERTY_COORD( EDA_DRAW_FRAME* aParentFrame, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ) : wxIntProperty( wxPG_LABEL, wxPG_LABEL, 0 ), - PGPROPERTY_DISTANCE( aParentFrame, REGEX_SIGNED_DISTANCE, aCoordType ) + PGPROPERTY_DISTANCE( aParentFrame, aCoordType ) { } diff --git a/include/properties/pg_properties.h b/include/properties/pg_properties.h index cbe7b9e93b..b1d3583dd1 100644 --- a/include/properties/pg_properties.h +++ b/include/properties/pg_properties.h @@ -41,7 +41,7 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* class PGPROPERTY_DISTANCE { public: - PGPROPERTY_DISTANCE( EDA_DRAW_FRAME* aParentFrame, const wxString& aRegEx, + PGPROPERTY_DISTANCE( EDA_DRAW_FRAME* aParentFrame, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ); virtual ~PGPROPERTY_DISTANCE() = 0; @@ -53,11 +53,28 @@ protected: protected: EDA_DRAW_FRAME* m_parentFrame; - std::unique_ptr m_regExValidator; ORIGIN_TRANSFORMS::COORD_TYPES_T m_coordType; }; +class PGPROPERTY_AREA : public wxIntProperty +{ +public: + PGPROPERTY_AREA( EDA_DRAW_FRAME* aParentFrame ); + +protected: + bool StringToValue( wxVariant& aVariant, const wxString& aText, + int aArgFlags = 0 ) const override; + + wxString ValueToString( wxVariant& aVariant, int aArgFlags = 0 ) const override; + + wxValidator* DoGetValidator() const override; + +protected: + EDA_DRAW_FRAME* m_parentFrame; +}; + + class PGPROPERTY_SIZE : public wxUIntProperty, public PGPROPERTY_DISTANCE { public: diff --git a/include/properties/property.h b/include/properties/property.h index 0d3df33ca0..b57a7076ce 100644 --- a/include/properties/property.h +++ b/include/properties/property.h @@ -55,6 +55,7 @@ enum PROPERTY_DISPLAY { PT_DEFAULT, ///< Default property for a given type PT_SIZE, ///< Size expressed in distance units (mm/inch) + PT_AREA, ///< Area expressed in distance units-squared (mm/inch) PT_COORD, ///< Coordinate expressed in distance units (mm/inch) PT_DEGREE, ///< Angle expressed in degrees PT_DECIDEGREE ///< Angle expressed in decidegrees diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index d3287d50d0..efcb546164 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -1545,10 +1545,10 @@ static struct ZONE_DESC if( zcMap.Choices().GetCount() == 0 ) { zcMap.Undefined( ZONE_CONNECTION::INHERITED ); - zcMap.Map( ZONE_CONNECTION::INHERITED, _HKI( "Inherited" ) ) - .Map( ZONE_CONNECTION::NONE, _HKI( "None" ) ) - .Map( ZONE_CONNECTION::THERMAL, _HKI( "Thermal reliefs" ) ) - .Map( ZONE_CONNECTION::FULL, _HKI( "Solid" ) ) + zcMap.Map( ZONE_CONNECTION::INHERITED, _HKI( "Inherited" ) ) + .Map( ZONE_CONNECTION::NONE, _HKI( "None" ) ) + .Map( ZONE_CONNECTION::THERMAL, _HKI( "Thermal reliefs" ) ) + .Map( ZONE_CONNECTION::FULL, _HKI( "Solid" ) ) .Map( ZONE_CONNECTION::THT_THERMAL, _HKI( "Thermal reliefs for PTH" ) ); } @@ -1557,10 +1557,20 @@ static struct ZONE_DESC if( zfmMap.Choices().GetCount() == 0 ) { zfmMap.Undefined( ZONE_FILL_MODE::POLYGONS ); - zfmMap.Map( ZONE_FILL_MODE::POLYGONS, _HKI( "Solid fill" ) ) + zfmMap.Map( ZONE_FILL_MODE::POLYGONS, _HKI( "Solid fill" ) ) .Map( ZONE_FILL_MODE::HATCH_PATTERN, _HKI( "Hatch pattern" ) ); } + ENUM_MAP& irmMap = ENUM_MAP::Instance(); + + if( irmMap.Choices().GetCount() == 0 ) + { + irmMap.Undefined( ISLAND_REMOVAL_MODE::ALWAYS ); + irmMap.Map( ISLAND_REMOVAL_MODE::ALWAYS, _HKI( "Always" ) ) + .Map( ISLAND_REMOVAL_MODE::NEVER, _HKI( "Never" ) ) + .Map( ISLAND_REMOVAL_MODE::AREA, _HKI( "Below area limit" ) ); + } + PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); REGISTER_TYPE( ZONE ); propMgr.InheritsAfter( TYPE_HASH( ZONE ), TYPE_HASH( BOARD_CONNECTED_ITEM ) ); @@ -1599,6 +1609,15 @@ static struct ZONE_DESC return false; }; + auto isBelowAreaIslandRemoval = + []( INSPECTABLE* aItem ) -> bool + { + if( ZONE* zone = dynamic_cast( aItem ) ) + return zone->GetIslandRemovalMode() == ISLAND_REMOVAL_MODE::AREA; + + return false; + }; + // Layer property is hidden because it only holds a single layer and zones actually use // a layer set propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), @@ -1613,8 +1632,7 @@ static struct ZONE_DESC _HKI( "Net Class" ), isCopperZone ); propMgr.AddProperty( new PROPERTY( _HKI( "Priority" ), - &ZONE::SetAssignedPriority, - &ZONE::GetAssignedPriority ) ) + &ZONE::SetAssignedPriority, &ZONE::GetAssignedPriority ) ) .SetAvailableFunc( isCopperZone ); propMgr.AddProperty( new PROPERTY( _HKI( "Name" ), @@ -1623,15 +1641,15 @@ static struct ZONE_DESC const wxString groupFill = _HKI( "Fill Style" ); propMgr.AddProperty( new PROPERTY_ENUM( _HKI( "Fill Mode" ), - &ZONE::SetFillMode, - &ZONE::GetFillMode ), - groupFill ); + &ZONE::SetFillMode, &ZONE::GetFillMode ), + groupFill ) + .SetAvailableFunc( isCopperZone ); propMgr.AddProperty( new PROPERTY( _HKI( "Orientation" ), - &ZONE::SetHatchOrientation, - &ZONE::GetHatchOrientation, - PROPERTY_DISPLAY::PT_DEGREE ), - groupFill ) + &ZONE::SetHatchOrientation, &ZONE::GetHatchOrientation, + PROPERTY_DISPLAY::PT_DEGREE ), + groupFill ) + .SetAvailableFunc( isCopperZone ) .SetWriteableFunc( isHatchedFill ); // TODO: Switch to translated @@ -1653,28 +1671,59 @@ static struct ZONE_DESC // TODO: Switch to translated propMgr.AddProperty( new PROPERTY( wxT( "Hatch Width" ), - &ZONE::SetHatchThickness, - &ZONE::GetHatchThickness, - PROPERTY_DISPLAY::PT_SIZE ), - groupFill ) + &ZONE::SetHatchThickness, &ZONE::GetHatchThickness, PROPERTY_DISPLAY::PT_SIZE ), + groupFill ) + .SetAvailableFunc( isCopperZone ) .SetWriteableFunc( isHatchedFill ) .SetValidator( atLeastMinWidthValidator ); // TODO: Switch to translated - propMgr.AddProperty( new PROPERTY( wxT( "Hatch Gap" ), &ZONE::SetHatchGap, - &ZONE::GetHatchGap, - PROPERTY_DISPLAY::PT_SIZE ), - groupFill ) + propMgr.AddProperty( new PROPERTY( wxT( "Hatch Gap" ), + &ZONE::SetHatchGap, &ZONE::GetHatchGap, PROPERTY_DISPLAY::PT_SIZE ), + groupFill ) + .SetAvailableFunc( isCopperZone ) .SetWriteableFunc( isHatchedFill ) .SetValidator( atLeastMinWidthValidator ); + // TODO: Switch to translated + propMgr.AddProperty( new PROPERTY( wxT( "Hatch Minimum Hole Ratio" ), + &ZONE::SetHatchHoleMinArea, &ZONE::GetHatchHoleMinArea ), + groupFill ) + .SetAvailableFunc( isCopperZone ) + .SetWriteableFunc( isHatchedFill ) + .SetValidator( PROPERTY_VALIDATORS::PositiveRatioValidator ); + // TODO: Smoothing effort needs to change to enum (in dialog too) - // TODO: Smoothing amount (double) - // Unexposed properties (HatchHoleMinArea / HatchBorderAlgorithm)? + // TODO: Switch to translated + propMgr.AddProperty( new PROPERTY( wxT( "Smoothing Effort" ), + &ZONE::SetHatchSmoothingLevel, &ZONE::GetHatchSmoothingLevel ), + groupFill ) + .SetAvailableFunc( isCopperZone ) + .SetWriteableFunc( isHatchedFill ); - const wxString groupOverrides = _HKI( "Overrides" ); + // TODO: Switch to translated + propMgr.AddProperty( new PROPERTY( wxT( "Smoothing Amount" ), + &ZONE::SetHatchSmoothingValue, &ZONE::GetHatchSmoothingValue ), + groupFill ) + .SetAvailableFunc( isCopperZone ) + .SetWriteableFunc( isHatchedFill ); - auto clearanceOverride = new PROPERTY( _HKI( "Clearance Override" ), + // TODO: Switch to translated + propMgr.AddProperty( new PROPERTY_ENUM( wxT( "Remove Islands" ), + &ZONE::SetIslandRemovalMode, &ZONE::GetIslandRemovalMode ), + groupFill ) + .SetAvailableFunc( isCopperZone ); + + // TODO: Switch to translated + propMgr.AddProperty( new PROPERTY( wxT( "Minimum Island Area" ), + &ZONE::SetMinIslandArea, &ZONE::GetMinIslandArea, PROPERTY_DISPLAY::PT_AREA ), + groupFill ) + .SetAvailableFunc( isCopperZone ) + .SetWriteableFunc( isBelowAreaIslandRemoval ); + + const wxString groupElectrical = _HKI( "Electrical" ); + + auto clearanceOverride = new PROPERTY( _HKI( "Clearance" ), &ZONE::SetLocalClearance, &ZONE::GetLocalClearance, PROPERTY_DISPLAY::PT_SIZE ); clearanceOverride->SetAvailableFunc( isCopperZone ); @@ -1705,13 +1754,14 @@ static struct ZONE_DESC thermalSpokeWidth->SetAvailableFunc( isCopperZone ); thermalSpokeWidth->SetValidator( atLeastMinWidthValidator ); - propMgr.AddProperty( clearanceOverride, groupOverrides ); - propMgr.AddProperty( minWidth, groupOverrides ); - propMgr.AddProperty( padConnections, groupOverrides ); - propMgr.AddProperty( thermalGap, groupOverrides ); - propMgr.AddProperty( thermalSpokeWidth, groupOverrides ); + propMgr.AddProperty( clearanceOverride, groupElectrical ); + propMgr.AddProperty( minWidth, groupElectrical ); + propMgr.AddProperty( padConnections, groupElectrical ); + propMgr.AddProperty( thermalGap, groupElectrical ); + propMgr.AddProperty( thermalSpokeWidth, groupElectrical ); } } _ZONE_DESC; IMPLEMENT_ENUM_TO_WXANY( ZONE_CONNECTION ) IMPLEMENT_ENUM_TO_WXANY( ZONE_FILL_MODE ) +IMPLEMENT_ENUM_TO_WXANY( ISLAND_REMOVAL_MODE ) diff --git a/pcbnew/zone.h b/pcbnew/zone.h index b4bbd2517f..154a55fdec 100644 --- a/pcbnew/zone.h +++ b/pcbnew/zone.h @@ -912,6 +912,7 @@ protected: #ifndef SWIG DECLARE_ENUM_TO_WXANY( ZONE_CONNECTION ) DECLARE_ENUM_TO_WXANY( ZONE_FILL_MODE ) +DECLARE_ENUM_TO_WXANY( ISLAND_REMOVAL_MODE ) #endif #endif // ZONE_H