KiCad PCB EDA Suite
dialog_position_relative.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) 2017-2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
25 #include <math/util.h> // for KiROUND
26 #include <tools/pcb_actions.h>
27 #include <widgets/tab_traversal.h>
28 #include <pcb_edit_frame.h>
29 #include <board_design_settings.h>
30 #include <trigo.h>
31 
32 // initialise statics
34 
35 
37  wxPoint& anchor ) :
39  m_toolMgr( aParent->GetToolManager() ),
40  m_translation( translation ),
41  m_anchor_position( anchor ),
42  m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
43  m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
44  m_stateX( 0.0 ),
45  m_stateY( 0.0 ),
46  m_stateRadius( 0.0 ),
47  m_stateTheta( 0.0 )
48 {
49  // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
50  // implementation on MSW
51  m_tabOrder = {
52  m_xEntry,
53  m_yEntry,
56  };
57 
58  // Configure display origin transforms
61 
63 
64  // and set up the entries according to the saved options
65  m_polarCoords->SetValue( m_options.polarCoords );
66  updateDialogControls( m_polarCoords->IsChecked() );
67 
70 
71  m_stdButtonsOK->SetDefault();
72 
74 }
75 
76 
77 void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
78 {
79  // convert to polar coordinates
80  r = hypot( x, y );
81 
82  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
83 }
84 
85 
86 bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxRealPoint& val, bool polar )
87 {
88  if( polar )
89  {
90  const double r = m_xOffset.GetDoubleValue();
91  const double q = m_yOffset.GetDoubleValue();
92 
93  val.x = r * cos( DEG2RAD( q / 10.0 ) );
94  val.y = r * sin( DEG2RAD( q / 10.0 ) );
95  }
96  else
97  {
98  // direct read
99  val.x = m_xOffset.GetDoubleValue();
100  val.y = m_yOffset.GetDoubleValue();
101  }
102 
103  // no validation to do here, but in future, you could return false here
104  return true;
105 }
106 
107 
108 void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
109 {
110  bool newPolar = m_polarCoords->IsChecked();
111  double xOffset = m_xOffset.GetDoubleValue();
112  double yOffset = m_yOffset.GetDoubleValue();
113  updateDialogControls( newPolar );
114 
115  if( newPolar )
116  {
117  if( xOffset != m_stateX || yOffset != m_stateY )
118  {
119  m_stateX = xOffset;
120  m_stateY = yOffset;
122  m_stateTheta *= 10.0;
123 
128  }
129  else
130  {
133  }
134  }
135  else
136  {
137  if( xOffset != m_stateRadius || yOffset != m_stateTheta )
138  {
139  m_stateRadius = xOffset;
140  m_stateTheta = yOffset;
141  m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
142  m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
143 
148  }
149  else
150  {
153  }
154  }
155 }
156 
157 
159 {
160  if( aPolar )
161  {
162  m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
163  m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
165  m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
166  m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
167  }
168  else
169  {
170  m_xOffset.SetLabel( _( "Offset X:" ) );
171  m_yOffset.SetLabel( _( "Offset Y:" ) );
173  m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
174  m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
175  }
176 }
177 
178 
179 void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
180 {
181  wxObject* obj = event.GetEventObject();
183  wxASSERT( posrelTool );
184 
185  wxPoint offset = posrelTool->GetSelectionAnchorPosition() - m_anchor_position;
186  double r, q;
187  ToPolarDeg( offset.x, offset.y, r, q );
188 
189 
190  if( obj == m_clearX )
191  {
192  m_stateX = offset.x;
195 
196  if( m_polarCoords->IsChecked() )
197  {
199  }
200  else
201  {
203  }
204  }
205  else if( obj == m_clearY )
206  {
207  m_stateY = offset.y;
208  m_yOffset.SetDoubleValue( q * 10 );
210 
211  if( m_polarCoords->IsChecked() )
212  {
214  }
215  else
216  {
218  }
219  }
220 }
221 
222 
223 void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
224 {
225  event.Skip();
226 
228  wxASSERT( posrelTool );
230 
231  Hide();
232 }
233 
234 
236 {
237  BOARD* board = (BOARD*) m_toolMgr->GetModel();
238 
240  m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
241 }
242 
243 
245 {
247 
248  m_anchor_position = (wxPoint) frame->GetScreen()->m_LocalOrigin;
249  m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
250 }
251 
252 
254 {
255  wxString reference = _( "<none selected>" );
256  BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
257 
258  if( item )
259  {
260  m_anchor_position = item->GetPosition();
261  reference = item->GetSelectMenuText( GetUserUnits() );
262  }
263 
264  m_referenceInfo->SetLabel( wxString::Format( "Reference item: %s", reference ) );
265 
266  Show( true );
267 }
268 
269 
270 void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
271 {
272  // for the output, we only deliver a Cartesian vector
273  wxRealPoint translation;
274  bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
275  m_translation.x = KiROUND( translation.x );
276  m_translation.y = KiROUND( translation.y );
277 
278  if( ok )
279  {
280  // save the settings
281  m_options.polarCoords = m_polarCoords->GetValue();
285  wxASSERT( posrelTool );
286 
288 
289  event.Skip();
290  }
291 }
292 
293 
294 void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
295 {
296  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
297 
298  if( obj->GetValue().IsEmpty() )
299  obj->SetValue( "0" );
300 
301  event.Skip();
302 }
The interactive edit tool.
Functions for manipulating tab traversal in forms and dialogs.
void OnUseGridOriginClick(wxCommandEvent &event) override
wxPoint m_GridOrigin
origin for grid offsets
wxPoint GetSelectionAnchorPosition() const
Return the position of the selected item(s)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:218
void OnOkClick(wxCommandEvent &event) override
double RAD2DEG(double rad)
Definition: trigo.h:230
DIALOG_POSITION_RELATIVE(PCB_BASE_FRAME *aParent, wxPoint &translation, wxPoint &anchor)
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:235
virtual wxPoint GetPosition() const
Definition: eda_item.h:252
void OnTextFocusLost(wxFocusEvent &event) override
Reset a text field to be 0 if it was exited while blank.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:589
EDA_ITEM * GetModel() const
Definition: tool_manager.h:290
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void OnClear(wxCommandEvent &event) override
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:119
void OnUseUserOriginClick(wxCommandEvent &event) override
void OnSelectItemClick(wxCommandEvent &event) override
#define _(s)
int RelativeItemSelectionMove(const wxPoint &anchor, const wxPoint &translation)
Position the m_position_relative_selection selection relative to anchor position using the given tran...
bool Show(bool show) override
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:294
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
Definition: unit_binder.cpp:92
bool GetTranslationInIU(wxRealPoint &val, bool polar)
Get the (Cartesian) translation described by the text entries.
Class DIALOG_POSITION_RELATIVE_BASE.
void SetLabel(const wxString &aLabel)
double DEG2RAD(double deg)
Definition: trigo.h:229
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
void OnPolarChanged(wxCommandEvent &event) override
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: eda_item.cpp:109
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:177
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual double GetDoubleValue()
Return the current value in Internal Units.
void ToPolarDeg(double x, double y, double &r, double &q)
Convert a given Cartesian point into a polar representation.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:90
static POSITION_RELATIVE_OPTIONS m_options