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 ); NO_SETTER( EDA_SHAPE, SHAPE_T ), &EDA_SHAPE::GetShape );
propMgr.AddProperty( shape ); propMgr.AddProperty( shape );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start X" ), 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" ), 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" ), 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" ), 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 // TODO: m_arcCenter, m_bezierC1, m_bezierC2, m_poly
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ), propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) ); &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: case PROPERTY_DISPLAY::PT_COORD:
ret = new PGPROPERTY_COORD(); ret = new PGPROPERTY_COORD();
static_cast<PGPROPERTY_COORD*>( ret )->SetCoordType( aProperty->CoordType() );
break; break;
case PROPERTY_DISPLAY::PT_DECIDEGREE: 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 ) ); 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 ); wxRegEx regDimension( m_regExValidator->GetRegEx(), wxRE_ICASE );
wxASSERT( regDimension.IsValid() ); wxASSERT( regDimension.IsValid() );
@ -198,6 +202,14 @@ bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString&
break; 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() ) if( aVariant.IsNull() || newValueIU != aVariant.GetLong() )
{ {
aVariant = newValueIU; aVariant = newValueIU;
@ -212,19 +224,26 @@ wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFla
{ {
wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG, wxEmptyString ); 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() ) switch( PROPERTY_MANAGER::Instance().GetUnits() )
{ {
case EDA_UNITS::INCHES: 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: 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: 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: case EDA_UNITS::UNSCALED:
return wxString::Format( wxT( "%li" ), aVariant.GetLong() ); return wxString::Format( wxT( "%li" ), distanceIU );
default: default:
// DEGREEs are handled by PGPROPERTY_ANGLE // 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, PGPROPERTY_COORD::PGPROPERTY_COORD( const wxString& aLabel, const wxString& aName,
long aValue ) long aValue, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType ) :
: wxIntProperty( aLabel, aName, aValue ), PGPROPERTY_DISTANCE( REGEX_SIGNED_DISTANCE ) 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(); PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.SetUnits( m_frame->GetUserUnits() ); propMgr.SetUnits( m_frame->GetUserUnits() );
propMgr.SetTransforms( &m_frame->GetOriginTransforms() );
std::set<PROPERTY_BASE*> commonProps; std::set<PROPERTY_BASE*> commonProps;
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() ); const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() );

View File

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

View File

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

View File

@ -37,6 +37,7 @@
class PROPERTY_BASE; class PROPERTY_BASE;
class TYPE_CAST_BASE; class TYPE_CAST_BASE;
class ORIGIN_TRANSFORMS;
///< Unique type identifier ///< Unique type identifier
using TYPE_ID = size_t; using TYPE_ID = size_t;
@ -170,6 +171,9 @@ public:
m_units = aUnits; 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 * Rebuild the list of all registered properties. Needs to be called
* once before GetProperty()/GetProperties() are used. * once before GetProperty()/GetProperties() are used.
@ -190,8 +194,10 @@ public:
std::vector<TYPE_ID> GetMatchingClasses( PROPERTY_BASE* aProperty ); std::vector<TYPE_ID> GetMatchingClasses( PROPERTY_BASE* aProperty );
private: private:
PROPERTY_MANAGER() PROPERTY_MANAGER() :
: m_dirty( false ), m_units( EDA_UNITS::MILLIMETRES ) m_dirty( false ),
m_units( EDA_UNITS::MILLIMETRES ),
m_originTransforms( nullptr )
{ {
} }
@ -241,6 +247,8 @@ private:
bool m_dirty; bool m_dirty;
EDA_UNITS m_units; 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.InheritsAfter( TYPE_HASH( BOARD_ITEM ), TYPE_HASH( EDA_ITEM ) );
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, int>( _HKI( "Position X" ), 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" ), 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" ), propMgr.AddProperty( new PROPERTY_ENUM<BOARD_ITEM, PCB_LAYER_ID>( _HKI( "Layer" ),
&BOARD_ITEM::SetLayer, &BOARD_ITEM::GetLayer ) ); &BOARD_ITEM::SetLayer, &BOARD_ITEM::GetLayer ) );
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, bool>( _HKI( "Locked" ), 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 ) ); &PCB_TRACK::SetWidth, &PCB_TRACK::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ), propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
new PROPERTY<PCB_TRACK, int, BOARD_ITEM>( _HKI( "Origin 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" ), propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
new PROPERTY<PCB_TRACK, int, BOARD_ITEM>( _HKI( "Origin 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" ), 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" ), 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 // Arc
REGISTER_TYPE( PCB_ARC ); REGISTER_TYPE( PCB_ARC );
@ -1251,14 +1255,18 @@ static struct TRACK_VIA_DESC
&PCB_ARC::SetWidth, &PCB_ARC::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) ); &PCB_ARC::SetWidth, &PCB_ARC::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ), propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
new PROPERTY<PCB_ARC, int, BOARD_ITEM>( _HKI( "Origin 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" ), propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
new PROPERTY<PCB_ARC, int, BOARD_ITEM>( _HKI( "Origin 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" ), 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" ), 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 // Via
REGISTER_TYPE( PCB_VIA ); REGISTER_TYPE( PCB_VIA );