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-2022 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>
28#include <pcb_edit_frame.h>
30#include <trigo.h>
31
32// initialise statics
34
35
38 m_toolMgr( aParent->GetToolManager() ),
39 m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
40 m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
41 m_stateX( 0.0 ),
42 m_stateY( 0.0 ),
43 m_stateRadius( 0.0 )
44{
45 // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics
46 // implementation on MSW
47 m_tabOrder = {
52 };
53
54 // Configure display origin transforms
57
59
60 // and set up the entries according to the saved options
62 updateDialogControls( m_polarCoords->IsChecked() );
63
64 updateAnchorInfo( nullptr );
65
68
70
72}
73
74
75void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, EDA_ANGLE& q )
76{
77 // convert to polar coordinates
78 r = hypot( x, y );
79
80 q = ( r != 0) ? EDA_ANGLE( VECTOR2D( x, y ) ) : ANGLE_0;
81}
82
83
85{
86 if( polar )
87 {
88 const double r = m_xOffset.GetDoubleValue();
90
91 val.x = KiROUND( r * q.Cos() );
92 val.y = KiROUND( r * q.Sin() );
93 }
94 else
95 {
96 // direct read
99 }
100
101 // no validation to do here, but in future, you could return false here
102 return true;
103}
104
105
106void 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
125 }
126 else
127 {
130 }
131 }
132 else
133 {
134 if( xOffset != m_stateRadius || yOffset != m_stateTheta.AsDegrees() )
135 {
136 m_stateRadius = xOffset;
137 m_stateTheta = EDA_ANGLE( yOffset, DEGREES_T );
140
145 }
146 else
147 {
150 }
151 }
152}
153
154
156{
157 if( aPolar )
158 {
159 m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
160 m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
162 m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
163 m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
164 }
165 else
166 {
167 m_xOffset.SetLabel( _( "Offset X:" ) );
168 m_yOffset.SetLabel( _( "Offset Y:" ) );
170 m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
171 m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
172 }
173}
174
175
176void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
177{
178 wxObject* obj = event.GetEventObject();
180 wxASSERT( posrelTool );
181
182 VECTOR2I offset = posrelTool->GetSelectionAnchorPosition() - getAnchorPos();
183 double r;
184 EDA_ANGLE q;
185 ToPolarDeg( offset.x, offset.y, r, q );
186
187 if( obj == m_clearX )
188 {
189 m_stateX = offset.x;
192
193 if( m_polarCoords->IsChecked() )
195 else
197 }
198 else if( obj == m_clearY )
199 {
200 m_stateY = offset.y;
203
204 if( m_polarCoords->IsChecked() )
206 else
208 }
209}
210
211
213{
214 event.Skip();
215
217 wxASSERT( posrelTool );
219
220 Hide();
221}
222
223
225{
226 switch( m_options.anchorType )
227 {
229 m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
230 break;
231
233 m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
234 break;
235
236 case ANCHOR_ITEM:
237 {
238 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
239 wxString msg = _( "<none selected>" );
240
241 if( aItem )
242 msg = aItem->GetSelectMenuText( &unitsProvider );
243
244 m_referenceInfo->SetLabel( wxString::Format( _( "Reference item: %s" ), msg ) );
245 break;
246 }
247 }
248}
249
250
252{
253 switch( m_options.anchorType )
254 {
256 return static_cast<BOARD*>( m_toolMgr->GetModel() )->GetDesignSettings().GetGridOrigin();
257
259 return static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() )->GetScreen()->m_LocalOrigin;
260
261 case ANCHOR_ITEM:
263 }
264
265 // Needed by some compilers to avoid a fatal compil error (no return value).
267}
268
269
271{
273 updateAnchorInfo( nullptr );
274}
275
276
278{
280 updateAnchorInfo( nullptr );
281}
282
283
285{
286 BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
287
289 updateAnchorInfo( item );
290
291 if( item )
293
294 Show( true );
295}
296
297
298void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
299{
300 // for the output, we only deliver a Cartesian vector
301 VECTOR2I translation;
302
303 if( getTranslationInIU( translation, m_polarCoords->IsChecked() ) )
304 {
305 // save the settings
306 m_options.polarCoords = m_polarCoords->GetValue();
309
311
312 posrelTool->RelativeItemSelectionMove( getAnchorPos(), translation );
313
314 event.Skip();
315 }
316}
317
318
320{
321 wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
322
323 if( obj->GetValue().IsEmpty() )
324 obj->SetValue( "0" );
325
326 event.Skip();
327}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
Class DIALOG_POSITION_RELATIVE_BASE.
bool getTranslationInIU(VECTOR2I &val, bool polar)
Get the (Cartesian) translation described by the text entries.
void OnUseGridOriginClick(wxCommandEvent &event) override
void OnPolarChanged(wxCommandEvent &event) override
void OnOkClick(wxCommandEvent &event) override
void updateAnchorInfo(BOARD_ITEM *aItem)
void OnClear(wxCommandEvent &event) override
static POSITION_RELATIVE_OPTIONS m_options
void OnSelectItemClick(wxCommandEvent &event) override
void OnTextFocusLost(wxFocusEvent &event) override
Reset a text field to be 0 if it was exited while blank.
void OnUseUserOriginClick(wxCommandEvent &event) override
void ToPolarDeg(double x, double y, double &r, EDA_ANGLE &q)
Convert a given Cartesian point into a polar representation.
DIALOG_POSITION_RELATIVE(PCB_BASE_FRAME *aParent)
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:222
bool Show(bool show) override
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 SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
double Sin() const
Definition: eda_angle.h:206
double AsDegrees() const
Definition: eda_angle.h:149
double Cos() const
Definition: eda_angle.h:221
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:251
virtual wxString GetSelectMenuText(UNITS_PROVIDER *aUnitsProvider) const
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: eda_item.cpp:108
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:272
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
The interactive edit tool.
int RelativeItemSelectionMove(const VECTOR2I &anchor, const VECTOR2I &translation)
Position the m_position_relative_selection selection relative to anchor position using the given tran...
VECTOR2I GetSelectionAnchorPosition() const
Return the position of the selected item(s)
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:296
EDA_ITEM * GetModel() const
Definition: tool_manager.h:292
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...
virtual EDA_ANGLE GetAngleValue()
virtual double GetDoubleValue()
Return the current value in Internal Units.
virtual void SetAngleValue(const EDA_ANGLE &aValue)
void SetLabel(const wxString &aLabel)
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:187
#define _(s)
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:412
E_SERIE r
Definition: eserie.cpp:41
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
Functions for manipulating tab traversal in forms and dialogs.
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:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617