KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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
161 m_yOffset.SetUnits( EDA_UNITS::DEGREES );
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 event.Skip();
227
229 wxASSERT( posrelTool );
231
232 Hide();
233}
234
235
237{
238 switch( m_options.anchorType )
239 {
241 m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
242 break;
243
245 m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
246 break;
247
248 case ANCHOR_ITEM:
249 {
250 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
251 wxString msg = _( "<none selected>" );
252
253 if( aItem )
254 msg = aItem->GetItemDescription( &unitsProvider, true );
255
256 m_referenceInfo->SetLabel( wxString::Format( _( "Reference item: %s" ), msg ) );
257 break;
258 }
259
260 case ANCHOR_POINT:
261 m_referenceInfo->SetLabel( wxString::Format(
262 _( "Reference location: selected point (%s, %s)" ),
265 break;
266 }
267}
268
269
271{
272 switch( m_options.anchorType )
273 {
275 return static_cast<BOARD*>( m_toolMgr->GetModel() )->GetDesignSettings().GetGridOrigin();
276
278 return static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() )->GetScreen()->m_LocalOrigin;
279
280 case ANCHOR_ITEM:
281 case ANCHOR_POINT:
283 }
284
285 // Needed by some compilers to avoid a fatal compil error (no return value).
287}
288
289
291{
293 updateAnchorInfo( nullptr );
294}
295
296
298{
300 updateAnchorInfo( nullptr );
301}
302
303
305{
306 BOARD_ITEM* item = nullptr;
307
308 if( aItem && aItem->IsBOARD_ITEM() )
309 item = static_cast<BOARD_ITEM*>( aItem );
310
312 updateAnchorInfo( item );
313
314 if( item )
316
317 Show( true );
318}
319
320
321void DIALOG_POSITION_RELATIVE::UpdateAnchor( std::optional<VECTOR2I> aPoint )
322{
324
325 if( aPoint )
326 m_anchorItemPosition = *aPoint;
327
328 updateAnchorInfo( nullptr );
329
330 Show( true );
331}
332
333
334void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
335{
336 // for the output, we only deliver a Cartesian vector
337 VECTOR2I translation;
338
339 if( getTranslationInIU( translation, m_polarCoords->IsChecked() ) )
340 {
341 // save the settings
342 m_options.polarCoords = m_polarCoords->GetValue();
345
347
348 posrelTool->RelativeItemSelectionMove( getAnchorPos(), translation );
349
350 event.Skip();
351 }
352}
353
354
356{
357 wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
358
359 if( obj->GetValue().IsEmpty() )
360 obj->SetValue( "0" );
361
362 event.Skip();
363}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:289
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 OnSelectPointClick(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:231
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:102
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_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:229
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:128
double Sin() const
Definition: eda_angle.h:170
double AsDegrees() const
Definition: eda_angle.h:113
double Cos() const
Definition: eda_angle.h:189
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:243
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:111
bool IsBOARD_ITEM() const
Definition: view_item.h:100
static TOOL_ACTION selectPositionRelativePoint
Definition: pcb_actions.h:325
static TOOL_ACTION selectPositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:324
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, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
TOOLS_HOLDER * GetToolHolder() const
Definition: tool_manager.h:402
EDA_ITEM * GetModel() const
Definition: tool_manager.h:398
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
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:188
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:401
@ DEGREES_T
Definition: eda_angle.h:31
Functions for manipulating tab traversal in forms and dialogs.
constexpr ret_type KiROUND(fp_type v, bool aQuiet=false)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:100
VECTOR2< double > VECTOR2D
Definition: vector2d.h:675