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
26#include <math/util.h> // for KiROUND
27#include <tools/pcb_actions.h>
29#include <pcb_edit_frame.h>
33#include <trigo.h>
34
35// initialise statics
37
38
41 m_toolMgr( aParent->GetToolManager() ),
42 m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ),
43 m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ),
44 m_stateX( 0.0 ),
45 m_stateY( 0.0 ),
46 m_stateRadius( 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 = {
55 };
56
57 // Configure display origin transforms
60
62
63 // and set up the entries according to the saved options
65 updateDialogControls( m_polarCoords->IsChecked() );
66
69
71
73}
74
75
76void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, EDA_ANGLE& q )
77{
78 // convert to polar coordinates
79 r = hypot( x, y );
80
81 q = ( r != 0) ? EDA_ANGLE( VECTOR2D( x, y ) ) : ANGLE_0;
82}
83
84
86{
87 if( polar )
88 {
89 const double r = m_xOffset.GetDoubleValue();
91
92 val.x = KiROUND( r * q.Cos() );
93 val.y = KiROUND( r * q.Sin() );
94 }
95 else
96 {
97 // direct read
100 }
101
102 // no validation to do here, but in future, you could return false here
103 return true;
104}
105
106
107void 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
126 }
127 else
128 {
131 }
132 }
133 else
134 {
135 if( xOffset != m_stateRadius || yOffset != m_stateTheta.AsDegrees() )
136 {
137 m_stateRadius = xOffset;
138 m_stateTheta = EDA_ANGLE( yOffset, DEGREES_T );
141
146 }
147 else
148 {
151 }
152 }
153}
154
155
157{
158 if( aPolar )
159 {
160 m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
161 m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
162 m_yOffset.SetUnits( EDA_UNITS::DEGREES );
163 m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
164 m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
165 }
166 else
167 {
168 m_xOffset.SetLabel( _( "Offset X:" ) );
169 m_yOffset.SetLabel( _( "Offset Y:" ) );
171 m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
172 m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
173 }
174}
175
176
177void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
178{
179 wxObject* obj = event.GetEventObject();
181 wxASSERT( posrelTool );
182
183 VECTOR2I offset = posrelTool->GetSelectionAnchorPosition() - getAnchorPos();
184 double r;
185 EDA_ANGLE q;
186 ToPolarDeg( offset.x, offset.y, r, q );
187
188 if( obj == m_clearX )
189 {
190 m_stateX = offset.x;
193
194 if( m_polarCoords->IsChecked() )
196 else
198 }
199 else if( obj == m_clearY )
200 {
201 m_stateY = offset.y;
204
205 if( m_polarCoords->IsChecked() )
207 else
209 }
210}
211
212
214{
215 event.Skip();
216
218 wxCHECK( pickerTool, /* void */ );
221 PCB_PICKER_TOOL::INTERACTIVE_PARAMS{ this, _( "Select reference item..." ) } );
222
223 Hide();
224}
225
226
228{
229 event.Skip();
230
232 wxCHECK( pickerTool, /* void */ );
235 PCB_PICKER_TOOL::INTERACTIVE_PARAMS{ this, _( "Select reference point..." ) } );
236
237 Hide();
238}
239
240
242{
243 switch( m_options.anchorType )
244 {
246 m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
247 break;
248
250 m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
251 break;
252
253 case ANCHOR_ITEM:
254 {
255 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
256 wxString msg = _( "<none selected>" );
257
258 if( aItem )
259 msg = aItem->GetItemDescription( &unitsProvider, true );
260
261 m_referenceInfo->SetLabel( wxString::Format( _( "Reference item: %s" ), msg ) );
262 break;
263 }
264
265 case ANCHOR_POINT:
266 m_referenceInfo->SetLabel( wxString::Format(
267 _( "Reference location: selected point (%s, %s)" ),
270 break;
271 }
272}
273
274
276{
277 switch( m_options.anchorType )
278 {
280 return static_cast<BOARD*>( m_toolMgr->GetModel() )->GetDesignSettings().GetGridOrigin();
281
283 return static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() )->GetScreen()->m_LocalOrigin;
284
285 case ANCHOR_ITEM:
286 case ANCHOR_POINT:
288 }
289
290 // Needed by some compilers to avoid a fatal compil error (no return value).
292}
293
294
296{
298 updateAnchorInfo( nullptr );
299}
300
301
303{
305 updateAnchorInfo( nullptr );
306}
307
308
310{
311 const BOARD_ITEM* item = nullptr;
312
313 if( aItem && aItem->IsBOARD_ITEM() )
314 item = static_cast<const BOARD_ITEM*>( aItem );
315
317 updateAnchorInfo( item );
318
319 if( item )
321
322 Show( true );
323}
324
325
326void DIALOG_POSITION_RELATIVE::UpdatePickedPoint( const std::optional<VECTOR2I>& aPoint )
327{
329
330 if( aPoint )
331 m_anchorItemPosition = *aPoint;
332
333 updateAnchorInfo( nullptr );
334
335 Show( true );
336}
337
338
339void DIALOG_POSITION_RELATIVE::OnOkClick( wxCommandEvent& event )
340{
341 // for the output, we only deliver a Cartesian vector
342 VECTOR2I translation;
343
344 if( getTranslationInIU( translation, m_polarCoords->IsChecked() ) )
345 {
346 // save the settings
347 m_options.polarCoords = m_polarCoords->GetValue();
350
352
353 posrelTool->RelativeItemSelectionMove( getAnchorPos(), translation );
354
355 event.Skip();
356 }
357}
358
359
361{
362 wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
363
364 if( obj->GetValue().IsEmpty() )
365 obj->SetValue( "0" );
366
367 event.Skip();
368}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
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:290
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 OnClear(wxCommandEvent &event) override
static POSITION_RELATIVE_OPTIONS m_options
void OnSelectItemClick(wxCommandEvent &event) override
void UpdatePickedPoint(const std::optional< VECTOR2I > &aPoint) override
void OnSelectPointClick(wxCommandEvent &event) override
void UpdatePickedItem(const EDA_ITEM *aItem) 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.
void updateAnchorInfo(const BOARD_ITEM *aItem)
DIALOG_POSITION_RELATIVE(PCB_BASE_FRAME *aParent)
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:242
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:240
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:130
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 selectPointInteractively
Definition: pcb_actions.h:332
static TOOL_ACTION selectItemInteractively
Selection of reference points/items.
Definition: pcb_actions.h:331
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
Generic tool for picking an item.
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:199
#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.
VECTOR2< double > VECTOR2D
Definition: vector2d.h:690