Limit radius in more places

This commit is contained in:
Seth Hillbrand
2025-08-30 08:19:35 -07:00
parent e3b550dd13
commit fe4ddc66eb
3 changed files with 73 additions and 3 deletions
+40 -2
View File
@@ -38,6 +38,8 @@
#include <geometry/roundrect.h>
#include <geometry/geometry_utils.h>
#include <macros.h>
#include <algorithm>
#include <properties/property_validators.h>
#include <math/util.h> // for KiROUND
#include <eda_item.h>
#include <plotters/plotter.h>
@@ -444,7 +446,18 @@ int EDA_SHAPE::GetCornerRadius() const
void EDA_SHAPE::SetCornerRadius( int aRadius )
{
m_cornerRadius = aRadius;
if( m_shape == SHAPE_T::RECTANGLE )
{
int width = std::abs( GetRectangleWidth() );
int height = std::abs( GetRectangleHeight() );
int maxRadius = std::min( width, height ) / 2;
m_cornerRadius = std::clamp( aRadius, 0, maxRadius );
}
else
{
m_cornerRadius = aRadius;
}
}
@@ -2704,7 +2717,32 @@ static struct EDA_SHAPE_DESC
&EDA_SHAPE::SetCornerRadius, &EDA_SHAPE::GetCornerRadius,
PROPERTY_DISPLAY::PT_SIZE, ORIGIN_TRANSFORMS::NOT_A_COORD ),
shapeProps )
.SetAvailableFunc( isRectangle );
.SetAvailableFunc( isRectangle )
.SetValidator( []( const wxAny&& aValue, EDA_ITEM* aItem ) -> VALIDATOR_RESULT
{
wxASSERT_MSG( aValue.CheckType<int>(),
"Expecting int-containing value" );
int radius = aValue.As<int>();
EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem );
if( !shape )
{
wxLogDebug( wxT( "Corner Radius Validator: Not an EDA_SHAPE" ) );
return std::nullopt;
}
int maxRadius = std::min( shape->GetRectangleWidth(),
shape->GetRectangleHeight() ) / 2;
if( radius > maxRadius )
return std::make_unique<VALIDATION_ERROR_TOO_LARGE<int>>( radius, maxRadius );
else if( radius < 0 )
return std::make_unique<VALIDATION_ERROR_TOO_SMALL<int>>( radius, 0 );
return std::nullopt;
} );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ),
@@ -41,6 +41,7 @@
#include <tool/actions.h>
#include <pcb_shape.h>
#include <macros.h>
#include <algorithm>
#include <widgets/unit_binder.h>
#include <tools/drawing_tool.h>
@@ -1207,6 +1208,10 @@ bool DIALOG_SHAPE_PROPERTIES::Validate()
if( m_fillCtrl->GetSelection() != UI_FILL_MODE::SOLID && m_thickness.GetValue() <= 0 )
errors.Add( _( "Line width must be greater than zero for an unfilled rectangle." ) );
if( m_item->GetCornerRadius() * 2 > std::min( m_item->GetRectangleWidth(),
m_item->GetRectangleHeight() ) )
errors.Add( _( "Corner radius must be less than or equal to half the smaller side." ) );
break;
case SHAPE_T::POLY:
+28 -1
View File
@@ -25,12 +25,39 @@
#include <boost/test/unit_test.hpp>
#include <pcb_shape.h>
#include <properties/property_mgr.h>
#include <properties/property.h>
#include <i18n_utility.h>
BOOST_AUTO_TEST_CASE( PCBShapeCornerRadius )
{
PCB_SHAPE shape( nullptr, SHAPE_T::RECTANGLE );
shape.SetStart( VECTOR2I( 0, 0 ) );
shape.SetEnd( VECTOR2I( 1000, 1000 ) );
shape.SetEnd( VECTOR2I( 1000, 600 ) );
shape.SetCornerRadius( 200 );
BOOST_CHECK_EQUAL( shape.GetCornerRadius(), 200 );
shape.SetCornerRadius( 400 );
BOOST_CHECK_EQUAL( shape.GetCornerRadius(), 300 );
shape.SetCornerRadius( -10 );
BOOST_CHECK_EQUAL( shape.GetCornerRadius(), 0 );
}
BOOST_AUTO_TEST_CASE( PCBShapeCornerRadiusValidation )
{
PCB_SHAPE shape( nullptr, SHAPE_T::RECTANGLE );
shape.SetStart( VECTOR2I( 0, 0 ) );
shape.SetEnd( VECTOR2I( 1000, 500 ) );
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.Rebuild();
PROPERTY_BASE* prop = propMgr.GetProperty( TYPE_HASH( EDA_SHAPE ), _HKI( "Corner Radius" ) );
auto resultTooLarge = prop->Validate( wxAny( 400 ), &shape );
BOOST_CHECK( resultTooLarge.has_value() );
auto resultOK = prop->Validate( wxAny( 200 ), &shape );
BOOST_CHECK( !resultOK.has_value() );
}