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 
30 // initialise statics
32 
33 
35  wxPoint& anchor ) :
37  m_toolMgr( aParent->GetToolManager() ),
38  m_translation( translation ),
39  m_anchor_position( anchor ),
40  m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
41  m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
42  m_stateX( 0.0 ),
43  m_stateY( 0.0 ),
44  m_stateRadius( 0.0 ),
45  m_stateTheta( 0.0 )
46 {
47  // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
48  // implementation on MSW
49  m_tabOrder = {
50  m_xEntry,
51  m_yEntry,
54  };
55 
56  // Configure display origin transforms
59 
61 
62  // and set up the entries according to the saved options
63  m_polarCoords->SetValue( m_options.polarCoords );
64  updateDialogControls( m_polarCoords->IsChecked() );
65 
68 
69  m_stdButtonsOK->SetDefault();
70 
72 }
73 
74 
75 void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
76 {
77  // convert to polar coordinates
78  r = hypot( x, y );
79 
80  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
81 }
82 
83 
84 bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxRealPoint& val, bool polar )
85 {
86  if( polar )
87  {
88  const double r = m_xOffset.GetDoubleValue();
89  const double q = m_yOffset.GetDoubleValue();
90 
91  val.x = r * cos( DEG2RAD( q / 10.0 ) );
92  val.y = r * sin( DEG2RAD( q / 10.0 ) );
93  }
94  else
95  {
96  // direct read
97  val.x = m_xOffset.GetDoubleValue();
98  val.y = m_yOffset.GetDoubleValue();
99  }
100 
101  // no validation to do here, but in future, you could return false here
102  return true;
103 }
104 
105 
106 void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
107 {
108  bool newPolar = m_polarCoords->IsChecked();
109  double xOffset = m_xOffset.GetDoubleValue();
110  double yOffset = m_yOffset.GetDoubleValue();
111  updateDialogControls( newPolar );
112 
113  if( newPolar )
114  {
115  if( xOffset != m_stateX || yOffset != m_stateY )
116  {
117  m_stateX = xOffset;
118  m_stateY = yOffset;
120  m_stateTheta *= 10.0;
121 
126  }
127  else
128  {
131  }
132  }
133  else
134  {
135  if( xOffset != m_stateRadius || yOffset != m_stateTheta )
136  {
137  m_stateRadius = xOffset;
138  m_stateTheta = yOffset;
139  m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
140  m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
141 
146  }
147  else
148  {
151  }
152  }
153 }
154 
155 
157 {
158  if( aPolar )
159  {
160  m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
161  m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
163  m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
164  m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
165  }
166  else
167  {
168  m_xOffset.SetLabel( _( "Offset X:" ) );
169  m_yOffset.SetLabel( _( "Offset Y:" ) );
171  m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
172  m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
173  }
174 }
175 
176 
177 void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
178 {
179  wxObject* obj = event.GetEventObject();
181  wxASSERT( posrelTool );
182 
183  wxPoint offset = posrelTool->GetSelectionAnchorPosition() - m_anchor_position;
184  double r, q;
185  ToPolarDeg( offset.x, offset.y, r, q );
186 
187 
188  if( obj == m_clearX )
189  {
190  m_stateX = offset.x;
193 
194  if( m_polarCoords->IsChecked() )
195  {
197  }
198  else
199  {
201  }
202  }
203  else if( obj == m_clearY )
204  {
205  m_stateY = offset.y;
206  m_yOffset.SetDoubleValue( q * 10 );
208 
209  if( m_polarCoords->IsChecked() )
210  {
212  }
213  else
214  {
216  }
217  }
218 }
219 
220 
221 void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
222 {
223  event.Skip();
224 
226  wxASSERT( posrelTool );
228 
229  Hide();
230 }
231 
232 
234 {
235  BOARD* board = (BOARD*) m_toolMgr->GetModel();
236 
238  m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
239 }
240 
241 
243 {
245 
247  m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
248 }
249 
250 
252 {
253  wxString reference = _( "<none selected>" );
254  BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
255 
256  if( item )
257  {
258  m_anchor_position = item->GetPosition();
259  reference = item->GetSelectMenuText( GetUserUnits() );
260  }
261 
262  m_referenceInfo->SetLabel( wxString::Format( "Reference item: %s", reference ) );
263 
264  Show( true );
265 }
266 
267 
268 void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
269 {
270  // for the output, we only deliver a Cartesian vector
271  wxRealPoint translation;
272  bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
273  m_translation.x = KiROUND( translation.x );
274  m_translation.y = KiROUND( translation.y );
275 
276  if( ok )
277  {
278  // save the settings
279  m_options.polarCoords = m_polarCoords->GetValue();
283  wxASSERT( posrelTool );
284 
286 
287  event.Skip();
288  }
289 }
290 
291 
292 void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
293 {
294  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
295 
296  if( obj->GetValue().IsEmpty() )
297  obj->SetValue( "0" );
298 
299  event.Skip();
300 }
POSITION_RELATIVE_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
Function GetSelectionAnchorPosition()
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:213
void OnOkClick(wxCommandEvent &event) override
double RAD2DEG(double rad)
Definition: trigo.h:220
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_POSITION_RELATIVE(PCB_BASE_FRAME *aParent, wxPoint &translation, wxPoint &anchor)
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:222
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:531
virtual wxPoint GetPosition() const
Definition: base_struct.h:337
void OnTextFocusLost(wxFocusEvent &event) override
EDA_ITEM * GetModel() const
Definition: tool_manager.h:296
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:114
void OnClear(wxCommandEvent &event) override
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:131
void OnUseUserOriginClick(wxCommandEvent &event) override
void OnSelectItemClick(wxCommandEvent &event) override
bool Show(bool show) override
int RelativeItemSelectionMove(wxPoint anchor, wxPoint translation)
Function RelativeItemSelectionMove()
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:300
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)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
double DEG2RAD(double deg)
Definition: trigo.h:219
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:178
#define _(s)
Definition: 3d_actions.cpp:33
void OnPolarChanged(wxCommandEvent &event) override
virtual wxString GetSelectMenuText(EDA_UNITS aUnits) const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
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:68
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
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)
Function SetOriginTransform Sets the current origin transform mode.
Definition: unit_binder.h:171
virtual void SetDoubleValue(double aValue)
Function SetDoubleValue Sets new value (in Internal Units) for the text field, taking care of units c...
virtual double GetDoubleValue()
Function GetValue Returns 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.
PCB_BASE_FRAME basic 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:62
virtual void SetUnits(EDA_UNITS aUnits, bool aUseMils=false)
Function SetUnits Normally not needed (as the UNIT_BINDER inherits from the parent frame),...
Definition: unit_binder.cpp:81
static POSITION_RELATIVE_OPTIONS m_options