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 {
43  // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
44  // implementation on MSW
45  m_tabOrder = {
46  m_xEntry,
47  m_yEntry,
50  };
51 
53 
54  // and set up the entries according to the saved options
55  m_polarCoords->SetValue( m_options.polarCoords );
56  updateDialogControls( m_polarCoords->IsChecked() );
57 
60 
61  m_stdButtonsOK->SetDefault();
62 
64 }
65 
66 
67 void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, double& q )
68 {
69  // convert to polar coordinates
70  r = hypot( x, y );
71 
72  q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
73 }
74 
75 
77 {
78  if( polar )
79  {
80  const int r = m_xOffset.GetValue();
81  const double q = m_yOffset.GetValue();
82 
83  val.x = r * cos( DEG2RAD( q / 10.0 ) );
84  val.y = r * sin( DEG2RAD( q / 10.0 ) );
85  }
86  else
87  {
88  // direct read
89  val.x = m_xOffset.GetValue();
90  val.y = m_yOffset.GetValue();
91  }
92 
93  // no validation to do here, but in future, you could return false here
94  return true;
95 }
96 
97 
98 void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
99 {
100  bool newPolar = m_polarCoords->IsChecked();
101  wxPoint val;
102 
103  // get the value as previously stored
104  GetTranslationInIU( val, !newPolar );
105 
106  // now switch the controls to the new representations
107  updateDialogControls( newPolar );
108 
109  if( newPolar )
110  {
111  // convert to polar coordinates
112  double r, q;
113  ToPolarDeg( val.x, val.y, r, q );
114 
115  m_xOffset.SetValue( KiROUND( r / 10.0) * 10 );
116  m_yOffset.SetValue( q * 10 );
117  }
118  else
119  {
120  // vector is already in Cartesian, so just render out
121  // note - round off the last decimal place (10nm) to prevent
122  // (some) rounding causing errors when round-tripping
123  // you can never eliminate entirely, however
124  m_xOffset.SetValue( KiROUND( val.x / 10.0 ) * 10 );
125  m_yOffset.SetValue( KiROUND( val.y / 10.0 ) * 10 );
126  }
127 }
128 
129 
131 {
132  if( aPolar )
133  {
134  m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
135  m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
137  }
138  else
139  {
140  m_xOffset.SetLabel( _( "Offset X:" ) );
141  m_yOffset.SetLabel( _( "Offset Y:" ) );
143  }
144 }
145 
146 
147 void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
148 {
149  wxObject* obj = event.GetEventObject();
150 
151  if( obj == m_clearX )
152  {
153  m_xOffset.SetValue( 0 );
154  }
155  else if( obj == m_clearY )
156  {
157  m_yOffset.SetValue( 0 );
158  }
159 }
160 
161 
162 void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event )
163 {
164  event.Skip();
165 
167  wxASSERT( posrelTool );
169 
170  Hide();
171 }
172 
173 
175 {
176  BOARD* board = (BOARD*) m_toolMgr->GetModel();
177 
178  m_anchor_position = board->GetGridOrigin();
179  m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
180 }
181 
182 
184 {
186 
188  m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
189 }
190 
191 
193 {
194  wxString reference = _( "<none selected>" );
195  BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
196 
197  if( item )
198  {
199  m_anchor_position = item->GetPosition();
200  reference = item->GetSelectMenuText( GetUserUnits() );
201  }
202 
203  m_referenceInfo->SetLabel( wxString::Format( "Reference item: %s", reference ) );
204 
205  Show( true );
206 }
207 
208 
209 void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
210 {
211  // for the output, we only deliver a Cartesian vector
212  bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
213 
214  if( ok )
215  {
216  // save the settings
217  m_options.polarCoords = m_polarCoords->GetValue();
221  wxASSERT( posrelTool );
222 
224 
225  event.Skip();
226  }
227 }
228 
229 
230 void DIALOG_POSITION_RELATIVE::OnTextFocusLost( wxFocusEvent& event )
231 {
232  wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
233 
234  if( obj->GetValue().IsEmpty() )
235  obj->SetValue( "0" );
236 
237  event.Skip();
238 }
POSITION_RELATIVE_TOOL.
Functions for manipulating tab traversal in forms and dialogs.
void OnUseGridOriginClick(wxCommandEvent &event) override
EDA_BASE_FRAME * GetEditFrame() const
Definition: tool_manager.h:268
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:210
void OnOkClick(wxCommandEvent &event) override
double RAD2DEG(double rad)
Definition: trigo.h:211
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:109
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:222
void OnTextFocusLost(wxFocusEvent &event) override
EDA_ITEM * GetModel() const
Definition: tool_manager.h:263
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
void OnClear(wxCommandEvent &event) override
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:132
void OnUseUserOriginClick(wxCommandEvent &event) override
void OnSelectItemClick(wxCommandEvent &event) override
bool Show(bool show) override
const wxPoint & GetGridOrigin() const
Definition: class_board.h:360
virtual const wxPoint GetPosition() const =0
int RelativeItemSelectionMove(wxPoint anchor, wxPoint translation)
Function RelativeItemSelectionMove()
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:210
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:160
#define _(s)
Definition: 3d_actions.cpp:31
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...
bool GetTranslationInIU(wxPoint &val, bool polar)
Get the (Cartesian) translation described by the text entries.
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:61
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual long long int GetValue()
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:114
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:68
static POSITION_RELATIVE_OPTIONS m_options