KiCad PCB EDA Suite
dialog_move_exact.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
5  * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
6  * Copyright (C) 2017 KiCad Developers, see CHANGELOG.TXT for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <wxPcbStruct.h>
27 #include <base_units.h>
28 #include <macros.h>
29 
30 #include <module_editor_frame.h>
31 
32 #include "dialog_move_exact.h"
33 
34 // initialise statics
36 
37 
39  DIALOG_MOVE_EXACT_BASE( aParent ),
40  m_translation( aParams.translation ),
41  m_rotation( aParams.rotation ),
42  m_origin( aParams.origin ),
43  m_anchor( aParams.anchor ),
44  m_allowOverride( aParams.allowOverride ),
45  m_editingFootprint( aParams.editingFootprint )
46 {
47  // set the unit labels
48  m_xUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
49  m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
50 
51  // tabbing goes through the entries in sequence
52  m_yEntry->MoveAfterInTabOrder( m_xEntry );
53  m_rotEntry->MoveAfterInTabOrder( m_yEntry );
54 
55  // and set up the entries according to the saved options
56  m_polarCoords->SetValue( m_options.polarCoords );
57  m_xEntry->SetValue( wxString::FromDouble( m_options.entry1 ) );
58  m_yEntry->SetValue( wxString::FromDouble( m_options.entry2 ) );
59  m_rotEntry->SetValue( wxString::FromDouble( m_options.entryRotation ) );
60  m_originChooser->SetSelection( m_options.origin );
61 
62  if( m_allowOverride )
63  {
66 
67  // ME_ANCHOR_FROM_LIBRARY is not in the wxChoice options so show the first choice instead
69  {
70  m_anchorChoice->SetSelection( ANCHOR_TOP_LEFT_PAD );
71  }
72  else
73  {
74  m_anchorChoice->SetSelection( m_options.anchor );
75  }
76 
78  {
79  // no footprint override necessary in this mode
80  m_cbOverride->Disable();
81  m_anchorChoice->Disable();
82  }
83 
84  if( m_editingFootprint )
85  {
86  // there is no point in showing the center footprint option when editing footprints
88  }
89  }
90  else
91  {
92  // hide the checkbox and choice control if overides are not allowed
93  bMainSizer->Hide( bAnchorSizer, true );
94  }
95 
96  if( wxPoint( 0, 0 ) == aParent->GetScreen()->m_O_Curseur )
97  {
98  // disble the user origin option when the user oigin is not set
99  m_originChooser->Enable( RELATIVE_TO_USER_ORIGIN, false );
100  m_originChooser->SetItemToolTip( RELATIVE_TO_USER_ORIGIN,
101  wxString( "The user origin is currently not set\n"
102  "Set it by using the <space> hotkey" ) );
103  }
104 
105  if( wxPoint( 0, 0 ) == aParent->GetGridOrigin() )
106  {
107  // disble the grid origin option when the user oigin is not set
108  m_originChooser->Enable( RELATIVE_TO_GRID_ORIGIN, false );
109  m_originChooser->SetItemToolTip( RELATIVE_TO_GRID_ORIGIN,
110  wxString( "The grid origin is currently not set\n"
111  "Set it by using the tool in the <place> menu" ) );
112  }
113 
114  if( wxPoint( 0, 0 ) == aParent->GetAuxOrigin() )
115  {
116  // disble the grid origin option when the drill/place oigin is not set
119  wxString( "The drill/place origin is currently not set\n"
120  "Set it by using the tool in the <place> menu" ) );
121  }
122 
123  updateDlgTexts( m_polarCoords->IsChecked() );
124 
125  m_stdButtonsOK->SetDefault();
126 
127  GetSizer()->SetSizeHints( this );
128  Layout();
129 }
130 
131 
133 {
134 }
135 
136 
137 void DIALOG_MOVE_EXACT::ToPolarDeg( double x, double y, double& r, double& q )
138 {
139  // convert to polar coordinates
140  r = hypot ( x, y );
141 
142  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
143 }
144 
145 
147 {
148  if( polar )
149  {
150  const int r = ValueFromTextCtrl( *m_xEntry );
151  const double q = DoubleValueFromString( DEGREES, m_yEntry->GetValue() );
152 
153  val.x = r * cos( DEG2RAD( q / 10.0 ) );
154  val.y = r * sin( DEG2RAD( q / 10.0 ) );
155  }
156  else
157  {
158  // direct read
159  val.x = ValueFromTextCtrl( *m_xEntry );
160  val.y = ValueFromTextCtrl( *m_yEntry );
161  }
162 
163  // no validation to do here, but in future, you could return false here
164  return true;
165 }
166 
167 
168 void DIALOG_MOVE_EXACT::OnPolarChanged( wxCommandEvent& event )
169 {
170  bool newPolar = m_polarCoords->IsChecked();
171  updateDlgTexts( newPolar );
172  wxPoint val;
173 
174  // get the value as previously stored
175  GetTranslationInIU( val, !newPolar );
176 
177  if( newPolar )
178  {
179  // convert to polar coordinates
180  double r, q;
181  ToPolarDeg( val.x, val.y, r, q );
182 
183  PutValueInLocalUnits( *m_xEntry, KiROUND( r / 10.0) * 10 );
184  m_yEntry->SetValue( wxString::FromDouble( q ) );
185  }
186  else
187  {
188  // vector is already in Cartesian, so just render out
189  // note - round off the last decimal place (10nm) to prevent
190  // (some) rounding causing errors when round-tripping
191  // you can never eliminate entirely, however
192  PutValueInLocalUnits( *m_xEntry, KiROUND( val.x / 10.0 ) * 10 );
193  PutValueInLocalUnits( *m_yEntry, KiROUND( val.y / 10.0 ) * 10 );
194  }
195  Layout();
196 }
197 
198 
199 void DIALOG_MOVE_EXACT::OnOriginChanged( wxCommandEvent& event )
200 {
201  if( m_originChooser->GetSelection() == RELATIVE_TO_CURRENT_POSITION )
202  {
203  //no need to override the achor in this mode since the reference in the current position
204  m_cbOverride->Disable();
205  m_anchorChoice->Disable();
206  }
207  else if( m_allowOverride )
208  {
209  m_cbOverride->Enable();
210 
211  if( m_cbOverride->IsChecked() )
212  m_anchorChoice->Enable();
213  }
214 }
215 
216 
217 void DIALOG_MOVE_EXACT::OnOverrideChanged( wxCommandEvent& event )
218 {
219  if( m_cbOverride->IsChecked() )
220  {
221  m_anchorChoice->Enable();
222  }
223  else
224  {
225  m_anchorChoice->Disable();
226  }
227 }
228 
229 
231 {
232  if( aPolar )
233  {
234  m_xLabel->SetLabelText( _( "Distance:" ) ); // Polar radius
235  m_yLabel->SetLabelText( _( "Angle:" ) ); // Polar theta or angle
236 
237  m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( DEGREES ) );
238  }
239  else
240  {
241  m_xLabel->SetLabelText( _( "Move vector X:" ) );
242  m_yLabel->SetLabelText( _( "Move vector Y:" ) );
243 
244  m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
245  }
246 }
247 
248 
249 void DIALOG_MOVE_EXACT::OnClear( wxCommandEvent& event )
250 {
251  wxObject* obj = event.GetEventObject();
252  wxTextCtrl* entry = NULL;
253 
254  if( obj == m_clearX )
255  {
256  entry = m_xEntry;
257  }
258  else if( obj == m_clearY )
259  {
260  entry = m_yEntry;
261  }
262  else if( obj == m_clearRot )
263  {
264  entry = m_rotEntry;
265  }
266 
267  if( entry )
268  entry->SetValue( "0" );
269 }
270 
271 
272 void DIALOG_MOVE_EXACT::OnOkClick( wxCommandEvent& event )
273 {
275  m_origin = static_cast<MOVE_EXACT_ORIGIN>( m_originChooser->GetSelection() );
276 
277  if( m_cbOverride->IsChecked() && m_allowOverride )
278  {
279  m_anchor = static_cast<MOVE_EXACT_ANCHOR>( m_anchorChoice->GetSelection() );
280  }
281  else
282  {
284  }
285 
286  // for the output, we only deliver a Cartesian vector
287  bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
288 
289  if( ok )
290  {
291  // save the settings
292  m_options.polarCoords = m_polarCoords->GetValue();
297  m_options.anchor = static_cast<MOVE_EXACT_ANCHOR>( m_anchorChoice->GetSelection() );
298  m_options.overrideAnchor = m_cbOverride->IsChecked();
299  event.Skip();
300  }
301 }
302 
303 
304 void DIALOG_MOVE_EXACT::OnTextFocusLost( wxFocusEvent& event )
305 {
306  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
307 
308  if( obj->GetValue().IsEmpty() )
309  obj->SetValue( "0" );
310 
311  event.Skip();
312 }
Definition of class FOOTPRINT_EDIT_FRAME.
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
MOVE_EXACT_ORIGIN
Implementation of conversion functions that require both schematic and board internal units...
Class DIALOG_MOVE_EXACT_BASE.
double RAD2DEG(double rad)
Definition: trigo.h:192
const wxPoint & GetGridOrigin() const override
Function GetGridOrigin returns the absolute coordinates of the origin of the snap grid...
MOVE_EXACT_ORIGIN & m_origin
wxPoint m_O_Curseur
Relative Screen cursor coordinate (on grid) in user units.
const wxPoint & GetAuxOrigin() const override
Function GetAuxOrigin returns the origin of the axis used for plotting and various exports...
MOVE_EXACT_ANCHOR
This file contains miscellaneous commonly used macros and functions.
void OnOkClick(wxCommandEvent &event) override
void OnPolarChanged(wxCommandEvent &event) override
DIALOG_MOVE_EXACT(PCB_BASE_FRAME *aParent, MOVE_PARAMETERS &aParams)
void updateDlgTexts(bool aPolar)
bool GetTranslationInIU(wxPoint &val, bool polar)
Get the (Cartesian) translation described by the text entries.
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit)
Definition: base_units.cpp:479
int ValueFromTextCtrl(const wxTextCtrl &aTextCtr)
Convert the number Value in a string according to the internal units and the selected unit (g_UserUni...
Definition: base_units.cpp:384
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
void OnTextFocusLost(wxFocusEvent &event) override
void OnClear(wxCommandEvent &event) override
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:265
double DEG2RAD(double deg)
Definition: trigo.h:191
void ToPolarDeg(double x, double y, double &r, double &q)
Convert a given Cartesian point into a polar representation.
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
MOVE_EXACT_ANCHOR & m_anchor
static MOVE_EXACT_OPTIONS m_options
void OnOriginChanged(wxCommandEvent &event) override
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:301
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
void OnOverrideChanged(wxCommandEvent &event) override