Handle coordinate transforms in properties system

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12320
This commit is contained in:
Jon Evans 2022-10-30 21:09:59 -04:00
parent 5be0ddca27
commit a5d685ff5c
8 changed files with 94 additions and 35 deletions

View File

@ -1636,13 +1636,17 @@ static struct EDA_SHAPE_DESC
NO_SETTER( EDA_SHAPE, SHAPE_T ), &EDA_SHAPE::GetShape );
propMgr.AddProperty( shape );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start X" ),
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD ) );
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD ) );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start Y" ),
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD ) );
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End X" ),
&EDA_SHAPE::SetEndX, &EDA_SHAPE::GetEndX, PROPERTY_DISPLAY::PT_COORD ) );
&EDA_SHAPE::SetEndX, &EDA_SHAPE::GetEndX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD ) );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End Y" ),
&EDA_SHAPE::SetEndY, &EDA_SHAPE::GetEndY, PROPERTY_DISPLAY::PT_COORD ) );
&EDA_SHAPE::SetEndY, &EDA_SHAPE::GetEndY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
// TODO: m_arcCenter, m_bezierC1, m_bezierC2, m_poly
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );

View File

@ -49,6 +49,7 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty )
case PROPERTY_DISPLAY::PT_COORD:
ret = new PGPROPERTY_COORD();
static_cast<PGPROPERTY_COORD*>( ret )->SetCoordType( aProperty->CoordType() );
break;
case PROPERTY_DISPLAY::PT_DECIDEGREE:
@ -123,7 +124,9 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty )
}
PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( const wxString& aRegEx )
PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( const wxString& aRegEx,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ) :
m_coordType( aCoordType )
{
m_regExValidator.reset( new REGEX_VALIDATOR( aRegEx ) );
}
@ -134,7 +137,8 @@ PGPROPERTY_DISTANCE::~PGPROPERTY_DISTANCE()
}
bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString& aText,
int aArgFlags ) const
{
wxRegEx regDimension( m_regExValidator->GetRegEx(), wxRE_ICASE );
wxASSERT( regDimension.IsValid() );
@ -198,6 +202,14 @@ bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString&
break;
}
ORIGIN_TRANSFORMS* transforms = PROPERTY_MANAGER::Instance().GetTransforms();
if( transforms )
{
newValueIU = transforms->FromDisplay( static_cast<long long int>( newValueIU ),
m_coordType );
}
if( aVariant.IsNull() || newValueIU != aVariant.GetLong() )
{
aVariant = newValueIU;
@ -212,19 +224,26 @@ wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFla
{
wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG, wxEmptyString );
long distanceIU = aVariant.GetLong();
ORIGIN_TRANSFORMS* transforms = PROPERTY_MANAGER::Instance().GetTransforms();
if( transforms )
distanceIU = transforms->ToDisplay( static_cast<long long int>( distanceIU ), m_coordType );
switch( PROPERTY_MANAGER::Instance().GetUnits() )
{
case EDA_UNITS::INCHES:
return wxString::Format( wxT( "%d in" ), pcbIUScale.IUToMils( aVariant.GetLong() ) / 1000.0 );
return wxString::Format( wxT( "%d in" ), pcbIUScale.IUToMils( distanceIU ) / 1000.0 );
case EDA_UNITS::MILS:
return wxString::Format( wxT( "%d mils" ), pcbIUScale.IUToMils( aVariant.GetLong() ) );
return wxString::Format( wxT( "%d mils" ), pcbIUScale.IUToMils( distanceIU ) );
case EDA_UNITS::MILLIMETRES:
return wxString::Format( wxT( "%g mm" ), pcbIUScale.IUTomm( aVariant.GetLong() ) );
return wxString::Format( wxT( "%g mm" ), pcbIUScale.IUTomm( distanceIU ) );
case EDA_UNITS::UNSCALED:
return wxString::Format( wxT( "%li" ), aVariant.GetLong() );
return wxString::Format( wxT( "%li" ), distanceIU );
default:
// DEGREEs are handled by PGPROPERTY_ANGLE
@ -250,8 +269,9 @@ wxValidator* PGPROPERTY_SIZE::DoGetValidator() const
PGPROPERTY_COORD::PGPROPERTY_COORD( const wxString& aLabel, const wxString& aName,
long aValue )
: wxIntProperty( aLabel, aName, aValue ), PGPROPERTY_DISTANCE( REGEX_SIGNED_DISTANCE )
long aValue, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ) :
wxIntProperty( aLabel, aName, aValue ),
PGPROPERTY_DISTANCE( REGEX_SIGNED_DISTANCE, aCoordType )
{
}

View File

@ -95,6 +95,7 @@ void PROPERTIES_PANEL::update( const SELECTION& aSelection )
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.SetUnits( m_frame->GetUserUnits() );
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
std::set<PROPERTY_BASE*> commonProps;
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() );

View File

@ -25,6 +25,7 @@
#include <wx/propgrid/property.h>
#include <wx/propgrid/props.h>
#include <common.h>
#include <origin_transforms.h>
class PROPERTY_BASE;
class REGEX_VALIDATOR;
@ -35,14 +36,18 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty );
class PGPROPERTY_DISTANCE
{
public:
PGPROPERTY_DISTANCE( const wxString& aRegEx );
PGPROPERTY_DISTANCE( const wxString& aRegEx,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD );
virtual ~PGPROPERTY_DISTANCE() = 0;
void SetCoordType( ORIGIN_TRANSFORMS::COORD_TYPES_T aType ) { m_coordType = aType; }
protected:
bool StringToDistance( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const;
wxString DistanceToString( wxVariant& aVariant, int aArgFlags = 0 ) const;
std::unique_ptr<REGEX_VALIDATOR> m_regExValidator;
ORIGIN_TRANSFORMS::COORD_TYPES_T m_coordType;
};
@ -70,7 +75,8 @@ class PGPROPERTY_COORD : public wxIntProperty, public PGPROPERTY_DISTANCE
{
public:
PGPROPERTY_COORD( const wxString& aLabel = wxPG_LABEL, const wxString& aName = wxPG_LABEL,
long aValue = 0 );
long aValue = 0,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD );
bool StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags = 0 ) const override
{

View File

@ -39,6 +39,8 @@
#include <typeindex>
#include <type_traits>
#include <origin_transforms.h>
class wxPGProperty;
class INSPECTABLE;
class PROPERTY_BASE;
@ -177,9 +179,11 @@ private:
///< Used to generate unique IDs. Must come up front so it's initialized before ctor.
public:
PROPERTY_BASE( const wxString& aName, PROPERTY_DISPLAY aDisplay = PT_DEFAULT ) :
PROPERTY_BASE( const wxString& aName, PROPERTY_DISPLAY aDisplay = PT_DEFAULT,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD ) :
m_name( aName ),
m_display( aDisplay ),
m_coordType( aCoordType ),
m_availFunc( [](INSPECTABLE*)->bool { return true; } )
{
}
@ -258,6 +262,8 @@ PROPERTY_BASE( const wxString& aName, PROPERTY_DISPLAY aDisplay = PT_DEFAULT ) :
return m_display;
}
ORIGIN_TRANSFORMS::COORD_TYPES_T CoordType() const { return m_coordType; }
protected:
template<typename T>
void set( void* aObject, T aValue )
@ -284,6 +290,7 @@ private:
private:
const wxString m_name;
const PROPERTY_DISPLAY m_display;
const ORIGIN_TRANSFORMS::COORD_TYPES_T m_coordType;
std::function<bool(INSPECTABLE*)> m_availFunc; ///< Eval to determine if prop is available
@ -300,18 +307,20 @@ public:
template<typename SetType, typename GetType>
PROPERTY( const wxString& aName,
void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )(),
PROPERTY_DISPLAY aDisplay = PT_DEFAULT )
PROPERTY_DISPLAY aDisplay = PT_DEFAULT,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD )
: PROPERTY( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay, aCoordType )
{
}
template<typename SetType, typename GetType>
PROPERTY( const wxString& aName,
void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )() const,
PROPERTY_DISPLAY aDisplay = PT_DEFAULT )
PROPERTY_DISPLAY aDisplay = PT_DEFAULT,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD )
: PROPERTY( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay, aCoordType )
{
}
@ -337,8 +346,8 @@ public:
protected:
PROPERTY( const wxString& aName, SETTER_BASE<Owner, T>* s, GETTER_BASE<Owner, T>* g,
PROPERTY_DISPLAY aDisplay )
: PROPERTY_BASE( aName, aDisplay ), m_setter( s ), m_getter( g ),
PROPERTY_DISPLAY aDisplay, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType )
: PROPERTY_BASE( aName, aDisplay, aCoordType ), m_setter( s ), m_getter( g ),
m_ownerHash( TYPE_HASH( Owner ) ), m_baseHash( TYPE_HASH( Base ) ),
m_typeHash( TYPE_HASH( BASE_TYPE ) )
{
@ -403,9 +412,10 @@ public:
template<typename SetType, typename GetType>
PROPERTY_ENUM( const wxString& aName,
void ( Base::*aSetter )( SetType ), GetType( Base::*aGetter )() const,
PROPERTY_DISPLAY aDisplay = PT_DEFAULT )
PROPERTY_DISPLAY aDisplay = PT_DEFAULT,
ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType = ORIGIN_TRANSFORMS::NOT_A_COORD )
: PROPERTY<Owner, T, Base>( aName, METHOD<Owner, T, Base>::Wrap( aSetter ),
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay )
METHOD<Owner, T, Base>::Wrap( aGetter ), aDisplay, aCoordType )
{
if ( std::is_enum<T>::value )
{

View File

@ -37,6 +37,7 @@
class PROPERTY_BASE;
class TYPE_CAST_BASE;
class ORIGIN_TRANSFORMS;
///< Unique type identifier
using TYPE_ID = size_t;
@ -170,6 +171,9 @@ public:
m_units = aUnits;
}
ORIGIN_TRANSFORMS* GetTransforms() const { return m_originTransforms; }
void SetTransforms( ORIGIN_TRANSFORMS* aTransforms ) { m_originTransforms = aTransforms; }
/**
* Rebuild the list of all registered properties. Needs to be called
* once before GetProperty()/GetProperties() are used.
@ -190,8 +194,10 @@ public:
std::vector<TYPE_ID> GetMatchingClasses( PROPERTY_BASE* aProperty );
private:
PROPERTY_MANAGER()
: m_dirty( false ), m_units( EDA_UNITS::MILLIMETRES )
PROPERTY_MANAGER() :
m_dirty( false ),
m_units( EDA_UNITS::MILLIMETRES ),
m_originTransforms( nullptr )
{
}
@ -241,6 +247,8 @@ private:
bool m_dirty;
EDA_UNITS m_units;
ORIGIN_TRANSFORMS* m_originTransforms;
};

View File

@ -254,9 +254,11 @@ static struct BOARD_ITEM_DESC
propMgr.InheritsAfter( TYPE_HASH( BOARD_ITEM ), TYPE_HASH( EDA_ITEM ) );
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, int>( _HKI( "Position X" ),
&BOARD_ITEM::SetX, &BOARD_ITEM::GetX, PROPERTY_DISPLAY::PT_COORD ) );
&BOARD_ITEM::SetX, &BOARD_ITEM::GetX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD) );
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, int>( _HKI( "Position Y" ),
&BOARD_ITEM::SetY, &BOARD_ITEM::GetY, PROPERTY_DISPLAY::PT_COORD ) );
&BOARD_ITEM::SetY, &BOARD_ITEM::GetY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD) );
propMgr.AddProperty( new PROPERTY_ENUM<BOARD_ITEM, PCB_LAYER_ID>( _HKI( "Layer" ),
&BOARD_ITEM::SetLayer, &BOARD_ITEM::GetLayer ) );
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, bool>( _HKI( "Locked" ),

View File

@ -1234,14 +1234,18 @@ static struct TRACK_VIA_DESC
&PCB_TRACK::SetWidth, &PCB_TRACK::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
new PROPERTY<PCB_TRACK, int, BOARD_ITEM>( _HKI( "Origin X" ),
&PCB_TRACK::SetX, &PCB_TRACK::GetX, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetX, &PCB_TRACK::GetX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
new PROPERTY<PCB_TRACK, int, BOARD_ITEM>( _HKI( "Origin Y" ),
&PCB_TRACK::SetY, &PCB_TRACK::GetY, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetY, &PCB_TRACK::GetY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End X" ),
&PCB_TRACK::SetEndX, &PCB_TRACK::GetEndX, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetEndX, &PCB_TRACK::GetEndX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD) );
propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End Y" ),
&PCB_TRACK::SetEndY, &PCB_TRACK::GetEndY, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetEndY, &PCB_TRACK::GetEndY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD) );
// Arc
REGISTER_TYPE( PCB_ARC );
@ -1251,14 +1255,18 @@ static struct TRACK_VIA_DESC
&PCB_ARC::SetWidth, &PCB_ARC::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
new PROPERTY<PCB_ARC, int, BOARD_ITEM>( _HKI( "Origin X" ),
&PCB_TRACK::SetX, &PCB_ARC::GetX, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetX, &PCB_ARC::GetX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
new PROPERTY<PCB_ARC, int, BOARD_ITEM>( _HKI( "Origin Y" ),
&PCB_TRACK::SetY, &PCB_ARC::GetY, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetY, &PCB_ARC::GetY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD) );
propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End X" ),
&PCB_TRACK::SetEndX, &PCB_ARC::GetEndX, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetEndX, &PCB_ARC::GetEndX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD) );
propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End Y" ),
&PCB_TRACK::SetEndY, &PCB_ARC::GetEndY, PROPERTY_DISPLAY::PT_COORD ) );
&PCB_TRACK::SetEndY, &PCB_ARC::GetEndY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD) );
// Via
REGISTER_TYPE( PCB_VIA );