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 The 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 updateDialogControls( m_polarCoords->IsChecked() );
64
66
68}
69
70
71void DIALOG_POSITION_RELATIVE::ToPolarDeg( double x, double y, double& r, EDA_ANGLE& q )
72{
73 // convert to polar coordinates
74 r = hypot( x, y );
75
76 q = ( r != 0) ? EDA_ANGLE( VECTOR2D( x, y ) ) : ANGLE_0;
77}
78
79
81{
82 if( polar )
83 {
84 const double r = m_xOffset.GetDoubleValue();
86
87 val.x = KiROUND( r * q.Cos() );
88 val.y = KiROUND( r * q.Sin() );
89 }
90 else
91 {
92 // direct read
95 }
96
97 // no validation to do here, but in future, you could return false here
98 return true;
99}
100
101
102void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event )
103{
104 bool newPolar = m_polarCoords->IsChecked();
105 double xOffset = m_xOffset.GetDoubleValue();
106 double yOffset = m_yOffset.GetDoubleValue();
107 updateDialogControls( newPolar );
108
109 if( newPolar )
110 {
111 if( xOffset != m_stateX || yOffset != m_stateY )
112 {
113 m_stateX = xOffset;
114 m_stateY = yOffset;
116
121 }
122 else
123 {
126 }
127 }
128 else
129 {
130 if( xOffset != m_stateRadius || yOffset != m_stateTheta.AsDegrees() )
131 {
132 m_stateRadius = xOffset;
133 m_stateTheta = EDA_ANGLE( yOffset, DEGREES_T );
136
141 }
142 else
143 {
146 }
147 }
148}
149
150
152{
153 if( aPolar )
154 {
155 m_xOffset.SetLabel( _( "Distance:" ) ); // Polar radius
156 m_yOffset.SetLabel( _( "Angle:" ) ); // Polar theta or angle
157 m_yOffset.SetUnits( EDA_UNITS::DEGREES );
158 m_clearX->SetToolTip( _( "Reset to the current distance from the reference position." ) );
159 m_clearY->SetToolTip( _( "Reset to the current angle from the reference position." ) );
160 }
161 else
162 {
163 m_xOffset.SetLabel( _( "Offset X:" ) );
164 m_yOffset.SetLabel( _( "Offset Y:" ) );
166 m_clearX->SetToolTip( _( "Reset to the current X offset from the reference position." ) );
167 m_clearY->SetToolTip( _( "Reset to the current Y offset from the reference position." ) );
168 }
169}
170
171
172void DIALOG_POSITION_RELATIVE::OnClear( wxCommandEvent& event )
173{
174 wxObject* obj = event.GetEventObject();
176 wxASSERT( posrelTool );
177
178 VECTOR2I offset = posrelTool->GetSelectionAnchorPosition() - getAnchorPos();
179 double r;
180 EDA_ANGLE q;
181 ToPolarDeg( offset.x, offset.y, r, q );
182
183 if( obj == m_clearX )
184 {
185 m_stateX = offset.x;
188
189 if( m_polarCoords->IsChecked() )
191 else
193 }
194 else if( obj == m_clearY )
195 {
196 m_stateY = offset.y;
199
200 if( m_polarCoords->IsChecked() )
202 else
204 }
205}
206
207
209{
210 event.Skip();
211
213 wxCHECK( pickerTool, /* void */ );
214
216 PCB_PICKER_TOOL::INTERACTIVE_PARAMS{ this, _( "Select reference item..." ) } );
217
218 Hide();
219}
220
221
223{
224 event.Skip();
225
227 wxCHECK( pickerTool, /* void */ );
228
229 // Hide, but do not close, the dialog
230 Hide();
231
233 PCB_PICKER_TOOL::INTERACTIVE_PARAMS { this, _( "Select reference point..." ) } );
234}
235
236
238{
239 switch( s_anchorType )
240 {
242 m_referenceInfo->SetLabel( _( "Reference location: grid origin" ) );
243 break;
244
246 m_referenceInfo->SetLabel( _( "Reference location: local coordinates origin" ) );
247 break;
248
249 case ANCHOR_ITEM:
250 {
251 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
252 wxString msg = _( "<none selected>" );
253
254 if( aItem )
255 msg = aItem->GetItemDescription( &unitsProvider, true );
256
257 m_referenceInfo->SetLabel( wxString::Format( _( "Reference item: %s" ), msg ) );
258 break;
259 }
260
261 case ANCHOR_POINT:
262 m_referenceInfo->SetLabel( wxString::Format( _( "Reference location: selected point (%s, %s)" ),
265 break;
266 }
267}
268
269
271{
272 switch( s_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 const BOARD_ITEM* item = nullptr;
307
308 if( aItem && aItem->IsBOARD_ITEM() )
309 item = static_cast<const BOARD_ITEM*>( aItem );
310
312 updateAnchorInfo( item );
313
314 if( item )
316
317 Show( true );
318}
319
320
321void DIALOG_POSITION_RELATIVE::UpdatePickedPoint( const 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 {
342
343 posrelTool->RelativeItemSelectionMove( getAnchorPos(), translation );
344
345 event.Skip();
346 }
347}
348
349
351{
352 wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
353
354 if( obj->GetValue().IsEmpty() )
355 obj->SetValue( "0" );
356
357 event.Skip();
358}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
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:317
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
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
ANCHOR_TYPE
Persistent dialog options.
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:256
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:75
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:254
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:111
double Sin() const
Definition: eda_angle.h:178
double AsDegrees() const
Definition: eda_angle.h:116
double Cos() const
Definition: eda_angle.h:197
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:98
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:272
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:144
bool IsBOARD_ITEM() const
Definition: view_item.h:102
static TOOL_ACTION selectPointInteractively
Definition: pcb_actions.h:311
static TOOL_ACTION selectItemInteractively
Selection of reference points/items.
Definition: pcb_actions.h:310
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:406
EDA_ITEM * GetModel() const
Definition: tool_manager.h:402
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:205
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:411
@ DEGREES_T
Definition: eda_angle.h:31
Functions for manipulating tab traversal in forms and dialogs.
VECTOR2< double > VECTOR2D
Definition: vector2d.h:694