Don't truncate polar coordinates in position relative dialog/move exact dialog
This commit is contained in:
parent
3f31d48b5e
commit
2f7ac2b5b4
|
@ -195,6 +195,12 @@ void UNIT_BINDER::SetValue( int aValue )
|
|||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::SetDoubleValue( double aValue )
|
||||
{
|
||||
SetValue( StringFromValue( m_units, aValue, false, m_useMils ) );
|
||||
}
|
||||
|
||||
|
||||
void UNIT_BINDER::SetValue( wxString aValue )
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
@ -257,6 +263,28 @@ long long int UNIT_BINDER::GetValue()
|
|||
}
|
||||
|
||||
|
||||
double UNIT_BINDER::GetDoubleValue()
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
auto staticText = dynamic_cast<wxStaticText*>( m_value );
|
||||
wxString value;
|
||||
|
||||
if( textEntry )
|
||||
{
|
||||
if( m_needsEval && m_eval.Process( textEntry->GetValue() ) )
|
||||
value = m_eval.Result();
|
||||
else
|
||||
value = textEntry->GetValue();
|
||||
}
|
||||
else if( staticText )
|
||||
value = staticText->GetLabel();
|
||||
else
|
||||
return 0.0;
|
||||
|
||||
return DoubleValueFromString( m_units, value, m_useMils );
|
||||
}
|
||||
|
||||
|
||||
bool UNIT_BINDER::IsIndeterminate() const
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
|
|
@ -71,6 +71,13 @@ public:
|
|||
|
||||
void SetValue( wxString aValue );
|
||||
|
||||
/**
|
||||
* Function SetDoubleValue
|
||||
* Sets new value (in Internal Units) for the text field, taking care of units conversion.
|
||||
* @param aValue is the new value.
|
||||
*/
|
||||
virtual void SetDoubleValue( double aValue );
|
||||
|
||||
/**
|
||||
* Function ChangeValue
|
||||
* Changes the value (in Internal Units) for the text field, taking care of units conversion
|
||||
|
@ -87,6 +94,12 @@ public:
|
|||
*/
|
||||
virtual long long int GetValue();
|
||||
|
||||
/**
|
||||
* Function GetValue
|
||||
* Returns the current value in Internal Units.
|
||||
*/
|
||||
virtual double GetDoubleValue();
|
||||
|
||||
/**
|
||||
* Function IsIndeterminate
|
||||
* Returns true if the control holds the indeterminate value (for instance, if it
|
||||
|
|
|
@ -41,7 +41,11 @@ DIALOG_MOVE_EXACT::DIALOG_MOVE_EXACT( PCB_BASE_FRAME *aParent, wxPoint& aTransla
|
|||
m_bbox( aBbox ),
|
||||
m_moveX( aParent, m_xLabel, m_xEntry, m_xUnit ),
|
||||
m_moveY( aParent, m_yLabel, m_yEntry, m_yUnit ),
|
||||
m_rotate( aParent, m_rotLabel, m_rotEntry, m_rotUnit )
|
||||
m_rotate( aParent, m_rotLabel, m_rotEntry, m_rotUnit ),
|
||||
m_stateX( 0.0 ),
|
||||
m_stateY( 0.0 ),
|
||||
m_stateRadius( 0.0 ),
|
||||
m_stateTheta( 0.0 )
|
||||
{
|
||||
// We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
|
||||
// implementation on MSW
|
||||
|
@ -66,8 +70,8 @@ DIALOG_MOVE_EXACT::DIALOG_MOVE_EXACT( PCB_BASE_FRAME *aParent, wxPoint& aTransla
|
|||
|
||||
// and set up the entries according to the saved options
|
||||
m_polarCoords->SetValue( m_options.polarCoords );
|
||||
m_moveX.SetValue( m_options.entry1 );
|
||||
m_moveY.SetValue( m_options.entry2 );
|
||||
m_moveX.SetDoubleValue( m_options.entry1 );
|
||||
m_moveY.SetDoubleValue( m_options.entry2 );
|
||||
|
||||
m_rotate.SetUnits( EDA_UNITS::DEGREES );
|
||||
m_rotate.SetValue( m_options.entryRotation );
|
||||
|
@ -115,12 +119,12 @@ void DIALOG_MOVE_EXACT::ToPolarDeg( double x, double y, double& r, double& q )
|
|||
}
|
||||
|
||||
|
||||
bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
|
||||
bool DIALOG_MOVE_EXACT::GetTranslationInIU( wxRealPoint& val, bool polar )
|
||||
{
|
||||
if( polar )
|
||||
{
|
||||
const int r = m_moveX.GetValue();
|
||||
const double q = m_moveY.GetValue();
|
||||
const double r = m_moveX.GetDoubleValue();
|
||||
const double q = m_moveY.GetDoubleValue();
|
||||
|
||||
val.x = r * cos( DEG2RAD( q / 10.0 ) );
|
||||
val.y = r * sin( DEG2RAD( q / 10.0 ) );
|
||||
|
@ -128,8 +132,8 @@ bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
|
|||
else
|
||||
{
|
||||
// direct read
|
||||
val.x = m_moveX.GetValue();
|
||||
val.y = m_moveY.GetValue();
|
||||
val.x = m_moveX.GetDoubleValue();
|
||||
val.y = m_moveY.GetDoubleValue();
|
||||
}
|
||||
|
||||
// no validation to do here, but in future, you could return false here
|
||||
|
@ -140,33 +144,50 @@ bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
|
|||
void DIALOG_MOVE_EXACT::OnPolarChanged( wxCommandEvent& event )
|
||||
{
|
||||
bool newPolar = m_polarCoords->IsChecked();
|
||||
wxPoint val;
|
||||
|
||||
// get the value as previously stored
|
||||
GetTranslationInIU( val, !newPolar );
|
||||
|
||||
// now switch the controls to the new representations
|
||||
double moveX = m_moveX.GetDoubleValue();
|
||||
double moveY = m_moveY.GetDoubleValue();
|
||||
updateDialogControls( newPolar );
|
||||
|
||||
if( newPolar )
|
||||
{
|
||||
// convert to polar coordinates
|
||||
double r, q;
|
||||
ToPolarDeg( val.x, val.y, r, q );
|
||||
if( moveX != m_stateX || moveY != m_stateY )
|
||||
{
|
||||
m_stateX = moveX;
|
||||
m_stateY = moveY;
|
||||
ToPolarDeg( m_stateX, m_stateY, m_stateRadius, m_stateTheta );
|
||||
m_stateTheta *= 10.0;
|
||||
|
||||
m_moveX.SetValue( KiROUND( r / 10.0) * 10 );
|
||||
m_moveY.SetValue( q * 10 );
|
||||
m_moveX.SetDoubleValue( m_stateRadius );
|
||||
m_stateRadius = m_moveX.GetDoubleValue();
|
||||
m_moveY.SetDoubleValue( m_stateTheta );
|
||||
m_stateTheta = m_moveY.GetDoubleValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
// vector is already in Cartesian, so just render out
|
||||
// note - round off the last decimal place (10nm) to prevent
|
||||
// (some) rounding causing errors when round-tripping
|
||||
// you can never eliminate entirely, however
|
||||
m_moveX.SetValue( KiROUND( val.x / 10.0 ) * 10 );
|
||||
m_moveY.SetValue( KiROUND( val.y / 10.0 ) * 10 );
|
||||
m_moveX.SetDoubleValue( m_stateRadius );
|
||||
m_moveY.SetDoubleValue( m_stateTheta );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( moveX != m_stateRadius || moveY != m_stateTheta )
|
||||
{
|
||||
m_stateRadius = moveX;
|
||||
m_stateTheta = moveY;
|
||||
m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
|
||||
m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
|
||||
|
||||
m_moveX.SetDoubleValue( m_stateX );
|
||||
m_stateX = m_moveX.GetDoubleValue();
|
||||
m_moveY.SetDoubleValue( m_stateY );
|
||||
m_stateY = m_moveY.GetDoubleValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_moveX.SetDoubleValue( m_stateX );
|
||||
m_moveY.SetDoubleValue( m_stateY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,7 +235,10 @@ void DIALOG_MOVE_EXACT::OnClear( wxCommandEvent& event )
|
|||
bool DIALOG_MOVE_EXACT::TransferDataFromWindow()
|
||||
{
|
||||
// for the output, we only deliver a Cartesian vector
|
||||
bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
|
||||
wxRealPoint translation;
|
||||
bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
|
||||
m_translation.x = KiROUND(translation.x);
|
||||
m_translation.y = KiROUND(translation.y);
|
||||
m_rotation = m_rotate.GetValue();
|
||||
m_rotationAnchor = m_menuIDs[ m_anchorOptions->GetSelection() ];
|
||||
|
||||
|
@ -222,8 +246,8 @@ bool DIALOG_MOVE_EXACT::TransferDataFromWindow()
|
|||
{
|
||||
// save the settings
|
||||
m_options.polarCoords = m_polarCoords->GetValue();
|
||||
m_options.entry1 = m_moveX.GetValue();
|
||||
m_options.entry2 = m_moveY.GetValue();
|
||||
m_options.entry1 = m_moveX.GetDoubleValue();
|
||||
m_options.entry2 = m_moveY.GetDoubleValue();
|
||||
m_options.entryRotation = m_rotate.GetValue();
|
||||
m_options.entryAnchorSelection = (size_t) std::max( m_anchorOptions->GetSelection(), 0 );
|
||||
return true;
|
||||
|
@ -247,8 +271,8 @@ void DIALOG_MOVE_EXACT::OnTextFocusLost( wxFocusEvent& event )
|
|||
void DIALOG_MOVE_EXACT::OnTextChanged( wxCommandEvent& event )
|
||||
{
|
||||
|
||||
double delta_x = m_moveX.GetValue();
|
||||
double delta_y = m_moveY.GetValue();
|
||||
double delta_x = m_moveX.GetDoubleValue();
|
||||
double delta_y = m_moveY.GetDoubleValue();
|
||||
double max_border = std::numeric_limits<int>::max() * 0.7071;
|
||||
|
||||
if( m_bbox.GetLeft() + delta_x < -max_border ||
|
||||
|
|
|
@ -57,6 +57,12 @@ private:
|
|||
|
||||
std::vector<ROTATION_ANCHOR> m_menuIDs;
|
||||
|
||||
double m_stateX;
|
||||
double m_stateY;
|
||||
double m_stateRadius;
|
||||
double m_stateTheta;
|
||||
|
||||
|
||||
public:
|
||||
// Constructor and destructor
|
||||
DIALOG_MOVE_EXACT(PCB_BASE_FRAME *aParent, wxPoint& aTranslate,
|
||||
|
@ -92,7 +98,7 @@ private:
|
|||
* @param polar interpret as polar coords
|
||||
* @return false if error (though the text conversion functions don't report errors)
|
||||
*/
|
||||
bool GetTranslationInIU ( wxPoint& val, bool polar );
|
||||
bool GetTranslationInIU( wxRealPoint& val, bool polar );
|
||||
|
||||
void buildRotationAnchorMenu();
|
||||
|
||||
|
|
|
@ -38,7 +38,11 @@ DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxP
|
|||
m_translation( translation ),
|
||||
m_anchor_position( anchor ),
|
||||
m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
|
||||
m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit )
|
||||
m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
|
||||
m_stateX( 0.0 ),
|
||||
m_stateY( 0.0 ),
|
||||
m_stateRadius( 0.0 ),
|
||||
m_stateTheta( 0.0 )
|
||||
{
|
||||
// We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
|
||||
// implementation on MSW
|
||||
|
@ -55,8 +59,8 @@ DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxP
|
|||
m_polarCoords->SetValue( m_options.polarCoords );
|
||||
updateDialogControls( m_polarCoords->IsChecked() );
|
||||
|
||||
m_xOffset.SetValue( m_options.entry1 );
|
||||
m_yOffset.SetValue( m_options.entry2 );
|
||||
m_xOffset.SetDoubleValue( m_options.entry1 );
|
||||
m_yOffset.SetDoubleValue( m_options.entry2 );
|
||||
|
||||
m_stdButtonsOK->SetDefault();
|
||||
|
||||
|
@ -73,12 +77,12 @@ void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double
|
|||
}
|
||||
|
||||
|
||||
bool DIALOG_POSITION_RELATIVE::GetTranslationInIU ( wxPoint& val, bool polar )
|
||||
bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxRealPoint& val, bool polar )
|
||||
{
|
||||
if( polar )
|
||||
{
|
||||
const int r = m_xOffset.GetValue();
|
||||
const double q = m_yOffset.GetValue();
|
||||
const double r = m_xOffset.GetDoubleValue();
|
||||
const double q = m_yOffset.GetDoubleValue();
|
||||
|
||||
val.x = r * cos( DEG2RAD( q / 10.0 ) );
|
||||
val.y = r * sin( DEG2RAD( q / 10.0 ) );
|
||||
|
@ -86,8 +90,8 @@ bool DIALOG_POSITION_RELATIVE::GetTranslationInIU ( wxPoint& val, bool polar )
|
|||
else
|
||||
{
|
||||
// direct read
|
||||
val.x = m_xOffset.GetValue();
|
||||
val.y = m_yOffset.GetValue();
|
||||
val.x = m_xOffset.GetDoubleValue();
|
||||
val.y = m_yOffset.GetDoubleValue();
|
||||
}
|
||||
|
||||
// no validation to do here, but in future, you could return false here
|
||||
|
@ -98,31 +102,49 @@ bool DIALOG_POSITION_RELATIVE::GetTranslationInIU ( wxPoint& val, bool polar )
|
|||
void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
|
||||
{
|
||||
bool newPolar = m_polarCoords->IsChecked();
|
||||
wxPoint val;
|
||||
|
||||
// get the value as previously stored
|
||||
GetTranslationInIU( val, !newPolar );
|
||||
|
||||
// now switch the controls to the new representations
|
||||
double xOffset = m_xOffset.GetDoubleValue();
|
||||
double yOffset = m_yOffset.GetDoubleValue();
|
||||
updateDialogControls( newPolar );
|
||||
|
||||
if( newPolar )
|
||||
{
|
||||
// convert to polar coordinates
|
||||
double r, q;
|
||||
ToPolarDeg( val.x, val.y, r, q );
|
||||
if( xOffset != m_stateX || yOffset != m_stateY )
|
||||
{
|
||||
m_stateX = xOffset;
|
||||
m_stateY = yOffset;
|
||||
ToPolarDeg( m_stateX, m_stateY, m_stateRadius, m_stateTheta );
|
||||
m_stateTheta *= 10.0;
|
||||
|
||||
m_xOffset.SetValue( KiROUND( r / 10.0) * 10 );
|
||||
m_yOffset.SetValue( q * 10 );
|
||||
m_xOffset.SetDoubleValue( m_stateRadius );
|
||||
m_stateRadius = m_xOffset.GetDoubleValue();
|
||||
m_yOffset.SetDoubleValue( m_stateTheta );
|
||||
m_stateTheta = m_yOffset.GetDoubleValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
// vector is already in Cartesian, so just render out
|
||||
// note - round off the last decimal place (10nm) to prevent
|
||||
// (some) rounding causing errors when round-tripping
|
||||
// you can never eliminate entirely, however
|
||||
m_xOffset.SetValue( KiROUND( val.x / 10.0 ) * 10 );
|
||||
m_yOffset.SetValue( KiROUND( val.y / 10.0 ) * 10 );
|
||||
m_xOffset.SetDoubleValue( m_stateRadius );
|
||||
m_yOffset.SetDoubleValue( m_stateTheta );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xOffset != m_stateRadius || yOffset != m_stateTheta )
|
||||
{
|
||||
m_stateRadius = xOffset;
|
||||
m_stateTheta = yOffset;
|
||||
m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
|
||||
m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
|
||||
|
||||
m_xOffset.SetDoubleValue( m_stateX );
|
||||
m_stateX = m_xOffset.GetDoubleValue();
|
||||
m_yOffset.SetDoubleValue( m_stateY );
|
||||
m_stateY = m_yOffset.GetDoubleValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_xOffset.SetDoubleValue( m_stateX );
|
||||
m_yOffset.SetDoubleValue( m_stateY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,14 +231,17 @@ void DIALOG_POSITION_RELATIVE::UpdateAnchor( EDA_ITEM* aItem )
|
|||
void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
|
||||
{
|
||||
// for the output, we only deliver a Cartesian vector
|
||||
bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
|
||||
wxRealPoint translation;
|
||||
bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
|
||||
m_translation.x = KiROUND( translation.x );
|
||||
m_translation.y = KiROUND( translation.y );
|
||||
|
||||
if( ok )
|
||||
{
|
||||
// save the settings
|
||||
m_options.polarCoords = m_polarCoords->GetValue();
|
||||
m_options.entry1 = m_xOffset.GetValue();
|
||||
m_options.entry2 = m_yOffset.GetValue();
|
||||
m_options.entry1 = m_xOffset.GetDoubleValue();
|
||||
m_options.entry2 = m_yOffset.GetDoubleValue();
|
||||
POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool<POSITION_RELATIVE_TOOL>();
|
||||
wxASSERT( posrelTool );
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ private:
|
|||
UNIT_BINDER m_xOffset;
|
||||
UNIT_BINDER m_yOffset;
|
||||
|
||||
double m_stateX;
|
||||
double m_stateY;
|
||||
double m_stateRadius;
|
||||
double m_stateTheta;
|
||||
|
||||
|
||||
public:
|
||||
// Constructor and destructor
|
||||
DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxPoint& translation, wxPoint& anchor );
|
||||
|
@ -79,7 +85,7 @@ private:
|
|||
* @param polar interpret as polar coords
|
||||
* @return false if error (though the text conversion functions don't report errors)
|
||||
*/
|
||||
bool GetTranslationInIU( wxPoint& val, bool polar );
|
||||
bool GetTranslationInIU( wxRealPoint& val, bool polar );
|
||||
|
||||
// Update controls and their labels after changing the coordinates type (polar/cartesian)
|
||||
void updateDialogControls( bool aPolar );
|
||||
|
|
Loading…
Reference in New Issue