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 
57 
58  // and set up the entries according to the saved options
59  m_polarCoords->SetValue( m_options.polarCoords );
60  updateDialogControls( m_polarCoords->IsChecked() );
61 
64 
65  m_stdButtonsOK->SetDefault();
66 
68 }
69 
70 
71 void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
72 {
73  // convert to polar coordinates
74  r = hypot( x, y );
75 
76  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
77 }
78 
79 
80 bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxRealPoint& val, bool polar )
81 {
82  if( polar )
83  {
84  const double r = m_xOffset.GetDoubleValue();
85  const double q = m_yOffset.GetDoubleValue();
86 
87  val.x = r * cos( DEG2RAD( q / 10.0 ) );
88  val.y = r * sin( DEG2RAD( q / 10.0 ) );
89  }
90  else
91  {
92  // direct read
93  val.x = m_xOffset.GetDoubleValue();
94  val.y = m_yOffset.GetDoubleValue();
95  }
96 
97  // no validation to do here, but in future, you could return false here
98  return true;
99 }
100 
101 
102 void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
103 {
104  bool newPolar = m_polarCoords->IsChecked();
105  double xOffset = m_xOffset.GetDoubleValue();
106  double yOffset = m_yOffset.GetDoubleValue();
107  updateDialogControls( newPolar );
108 
109  if( newPolar )
110  {
111  if( xOffset != m_stateX || yOffset != m_stateY )
112  {
113  m_stateX = xOffset;
114  m_stateY = yOffset;
116  m_stateTheta *= 10.0;
117 
122  }
123  else
124  {
127  }
128  }
129  else
130  {
131  if( xOffset != m_stateRadius || yOffset != m_stateTheta )
132  {
133  m_stateRadius = xOffset;
134  m_stateTheta = yOffset;
135  m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
136  m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
137 
142  }
143  else
144  {
147  }
148  }
149 }
150 
151 
153 {
154  if( aPolar )
155  {
156  m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
157  m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
159  m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
160  m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
161  }
162  else
163  {
164  m_xOffset.SetLabel( _( "Offset X:" ) );
165  m_yOffset.SetLabel( _( "Offset Y:" ) );
167  m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
168  m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
169  }
170 }
171 
172 
173 void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
174 {
175  wxObject* obj = event.GetEventObject();
177  wxASSERT( posrelTool );
178 
179  wxPoint offset = posrelTool->GetSelectionAnchorPosition() - m_anchor_position;
180  double r, q;
181  ToPolarDeg( offset.x, offset.y, r, q );
182 
183 
184  if( obj == m_clearX )
185  {
186  m_stateX = offset.x;
189 
190  if( m_polarCoords->IsChecked() )
191  {
193  }
194  else
195  {
197  }
198  }
199  else if( obj == m_clearY )
200  {
201  m_stateY = offset.y;
202  m_yOffset.SetDoubleValue( q * 10 );
204 
205  if( m_polarCoords->IsChecked() )
206  {
208  }
209  else
210  {
212  }
213  }
214 }
215 
216 
217 void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
218 {
219  event.Skip();
220 
222  wxASSERT( posrelTool );
224 
225  Hide();
226 }
227 
228 
230 {
231  BOARD* board = (BOARD*) m_toolMgr->GetModel();
232 
234  m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
235 }
236 
237 
239 {
241 
243  m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
244 }
245 
246 
248 {
249  wxString reference = _( "<none selected>" );
250  BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
251 
252  if( item )
253  {
254  m_anchor_position = item->GetPosition();
255  reference = item->GetSelectMenuText( GetUserUnits() );
256  }
257 
258  m_referenceInfo->SetLabel( wxString::Format( "Reference item: %s", reference ) );
259 
260  Show( true );
261 }
262 
263 
264 void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
265 {
266  // for the output, we only deliver a Cartesian vector
267  wxRealPoint translation;
268  bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
269  m_translation.x = KiROUND( translation.x );
270  m_translation.y = KiROUND( translation.y );
271 
272  if( ok )
273  {
274  // save the settings
275  m_options.polarCoords = m_polarCoords->GetValue();
279  wxASSERT( posrelTool );
280 
282 
283  event.Skip();
284  }
285 }
286 
287 
288 void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
289 {
290  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
291 
292  if( obj->GetValue().IsEmpty() )
293  obj->SetValue( "0" );
294 
295  event.Skip();
296 }
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:215
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:218
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
void OnTextFocusLost(wxFocusEvent &event) override
EDA_ITEM * GetModel() const
Definition: tool_manager.h:291
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
virtual const wxPoint GetPosition() const
Definition: base_struct.h:337
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:295
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:205
double DEG2RAD(double deg)
Definition: trigo.h:214
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:180
#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.
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:64
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:79
static POSITION_RELATIVE_OPTIONS m_options