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 <trigo.h>
30 
31 // initialise statics
33 
34 
36  wxPoint& anchor ) :
38  m_toolMgr( aParent->GetToolManager() ),
39  m_translation( translation ),
40  m_anchor_position( anchor ),
41  m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
42  m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
43  m_stateX( 0.0 ),
44  m_stateY( 0.0 ),
45  m_stateRadius( 0.0 ),
46  m_stateTheta( 0.0 )
47 {
48  // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
49  // implementation on MSW
50  m_tabOrder = {
51  m_xEntry,
52  m_yEntry,
55  };
56 
57  // Configure display origin transforms
60 
62 
63  // and set up the entries according to the saved options
64  m_polarCoords->SetValue( m_options.polarCoords );
65  updateDialogControls( m_polarCoords->IsChecked() );
66 
69 
70  m_stdButtonsOK->SetDefault();
71 
73 }
74 
75 
76 void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
77 {
78  // convert to polar coordinates
79  r = hypot( x, y );
80 
81  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
82 }
83 
84 
85 bool DIALOG_POSITION_RELATIVE::GetTranslationInIU( wxRealPoint& val, bool polar )
86 {
87  if( polar )
88  {
89  const double r = m_xOffset.GetDoubleValue();
90  const double q = m_yOffset.GetDoubleValue();
91 
92  val.x = r * cos( DEG2RAD( q / 10.0 ) );
93  val.y = r * sin( DEG2RAD( q / 10.0 ) );
94  }
95  else
96  {
97  // direct read
98  val.x = m_xOffset.GetDoubleValue();
99  val.y = m_yOffset.GetDoubleValue();
100  }
101 
102  // no validation to do here, but in future, you could return false here
103  return true;
104 }
105 
106 
107 void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
108 {
109  bool newPolar = m_polarCoords->IsChecked();
110  double xOffset = m_xOffset.GetDoubleValue();
111  double yOffset = m_yOffset.GetDoubleValue();
112  updateDialogControls( newPolar );
113 
114  if( newPolar )
115  {
116  if( xOffset != m_stateX || yOffset != m_stateY )
117  {
118  m_stateX = xOffset;
119  m_stateY = yOffset;
121  m_stateTheta *= 10.0;
122 
127  }
128  else
129  {
132  }
133  }
134  else
135  {
136  if( xOffset != m_stateRadius || yOffset != m_stateTheta )
137  {
138  m_stateRadius = xOffset;
139  m_stateTheta = yOffset;
140  m_stateX = m_stateRadius * cos( DEG2RAD( m_stateTheta / 10.0 ) );
141  m_stateY = m_stateRadius * sin( DEG2RAD( m_stateTheta / 10.0 ) );
142 
147  }
148  else
149  {
152  }
153  }
154 }
155 
156 
158 {
159  if( aPolar )
160  {
161  m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
162  m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
164  m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
165  m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
166  }
167  else
168  {
169  m_xOffset.SetLabel( _( "Offset X:" ) );
170  m_yOffset.SetLabel( _( "Offset Y:" ) );
172  m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
173  m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
174  }
175 }
176 
177 
178 void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
179 {
180  wxObject* obj = event.GetEventObject();
182  wxASSERT( posrelTool );
183 
184  wxPoint offset = posrelTool->GetSelectionAnchorPosition() - m_anchor_position;
185  double r, q;
186  ToPolarDeg( offset.x, offset.y, r, q );
187 
188 
189  if( obj == m_clearX )
190  {
191  m_stateX = offset.x;
194 
195  if( m_polarCoords->IsChecked() )
196  {
198  }
199  else
200  {
202  }
203  }
204  else if( obj == m_clearY )
205  {
206  m_stateY = offset.y;
207  m_yOffset.SetDoubleValue( q * 10 );
209 
210  if( m_polarCoords->IsChecked() )
211  {
213  }
214  else
215  {
217  }
218  }
219 }
220 
221 
222 void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
223 {
224  event.Skip();
225 
227  wxASSERT( posrelTool );
229 
230  Hide();
231 }
232 
233 
235 {
236  BOARD* board = (BOARD*) m_toolMgr->GetModel();
237 
239  m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
240 }
241 
242 
244 {
246 
247  m_anchor_position = (wxPoint) frame->GetScreen()->m_LocalOrigin;
248  m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
249 }
250 
251 
253 {
254  wxString reference = _( "<none selected>" );
255  BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
256 
257  if( item )
258  {
259  m_anchor_position = item->GetPosition();
260  reference = item->GetSelectMenuText( GetUserUnits() );
261  }
262 
263  m_referenceInfo->SetLabel( wxString::Format( "Reference item: %s", reference ) );
264 
265  Show( true );
266 }
267 
268 
269 void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
270 {
271  // for the output, we only deliver a Cartesian vector
272  wxRealPoint translation;
273  bool ok = GetTranslationInIU( translation, m_polarCoords->IsChecked() );
274  m_translation.x = KiROUND( translation.x );
275  m_translation.y = KiROUND( translation.y );
276 
277  if( ok )
278  {
279  // save the settings
280  m_options.polarCoords = m_polarCoords->GetValue();
284  wxASSERT( posrelTool );
285 
287 
288  event.Skip();
289  }
290 }
291 
292 
293 void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
294 {
295  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
296 
297  if( obj->GetValue().IsEmpty() )
298  obj->SetValue( "0" );
299 
300  event.Skip();
301 }
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:82
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:219
void OnOkClick(wxCommandEvent &event) override
double RAD2DEG(double rad)
Definition: trigo.h:232
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:141
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:239
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
virtual wxPoint GetPosition() const
Definition: eda_item.h:301
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:98
void OnClear(wxCommandEvent &event) override
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:120
void OnUseUserOriginClick(wxCommandEvent &event) override
void OnSelectItemClick(wxCommandEvent &event) override
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
int RelativeItemSelectionMove(wxPoint anchor, wxPoint translation)
Position the m_position_relative_selection selection relative to anchor position using the given tran...
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:300
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:81
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:231
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
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:123
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:68
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
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:173
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:94
static POSITION_RELATIVE_OPTIONS m_options