KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_create_array.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 <wx/msgdlg.h>
27
28#include <base_units.h>
29#include <footprint.h>
30#include <pcb_edit_frame.h>
31#include <tools/pcb_actions.h>
33#include <tool/tool_manager.h>
35
36
41{
47
48 bool m_OptionsSet = true;
49
50 long m_GridNx = 5;
51 long m_GridNy = 5;
52 long m_GridDx = pcbIUScale.mmToIU( 2.54 );
53 long m_GridDy = pcbIUScale.mmToIU( 2.54 );
54 long m_GridOffsetX = 0;
55 long m_GridOffsetY = 0;
56 long m_GridStagger = 1;
57 bool m_GridStaggerRows = true;
60
61 bool m_GridRenumberPads = true;
62 long m_GridNumberingAxis = 0; // h then v
63 bool m_GridNumReverseAlt = false;
64 long m_GridNumStartSet = 1; // use specified start
65 long m_Grid2dArrayNumbering = 0; // linear numbering
66 long m_GridPrimaryAxisScheme = 0; // numeric
67 long m_GridSecondaryAxisScheme = 0; // numeric
68 wxString m_GridPrimaryNumOffset = wxT( "1" ); // numeric
69 wxString m_GridSecondaryNumOffset = wxT( "1" ); // numeric
72
73 long m_CircCentreX = 0;
74 long m_CircCentreY = 0;
76 long m_CircleDirection = 0; // clockwise
78 long m_CircCount = 4;
80 long m_CircNumStartSet = 1; // use specified start
82 wxString m_CircNumberingOffset = wxT("1");
85 long m_ArrayTypeTab = 0; // start on grid view
86 bool m_SelectionArrange = false;
87 bool m_SelectionDuplicate = true; // Duplicate by default
89 bool m_FootprintReannotate = true; // Assign unique by default
90};
91
92// Persistent options settings
94
103
108static const std::vector<NUMBERING_LIST_DATA> numberingTypeData {
109 {
111 _( "Numerals (0,1,2,...,9,10)" ),
112 },
113 {
115 _( "Hexadecimal (0,1,...,F,10,...)" ),
116 },
117 {
119 _( "Alphabet, minus IOSQXZ" ),
120 },
121 {
123 _( "Alphabet, full 26 characters" ),
124 },
125};
126
128 std::unique_ptr<ARRAY_OPTIONS>& aSettings,
129 bool aIsFootprintEditor, const VECTOR2I& aOrigPos ) :
130 DIALOG_CREATE_ARRAY_BASE( aParent ),
131 m_frame( aParent ),
132 m_settings( aSettings ),
133 m_originalItemPosition( aOrigPos ), m_isFootprintEditor( aIsFootprintEditor ),
143{
144 // Configure display origin transforms
151
152 // Set up numbering scheme drop downs character set strings
153 for( const auto& numData : numberingTypeData )
154 {
155 const wxString label = wxGetTranslation( numData.m_label );
156 void* clientData = (void*) &numData;
157
158 m_choicePriAxisNumbering->Append( label, clientData );
159 m_choiceSecAxisNumbering->Append( label, clientData );
160 m_choiceCircNumbering->Append( label, clientData );
161 }
162
163 m_choicePriAxisNumbering->SetSelection( 0 );
164 m_choiceSecAxisNumbering->SetSelection( 0 );
165 m_choiceCircNumbering->SetSelection( 0 );
166
169
170 // bind grid options to persister
171 m_cfg_persister.Add( *m_entryNx, s_arrayOptions.m_GridNx );
172 m_cfg_persister.Add( *m_entryNy, s_arrayOptions.m_GridNy );
175
176 m_cfg_persister.Add( m_hOffset, s_arrayOptions.m_GridOffsetX );
177 m_cfg_persister.Add( m_vOffset, s_arrayOptions.m_GridOffsetY );
178 m_cfg_persister.Add( *m_entryStagger, s_arrayOptions.m_GridStagger );
179
180 m_cfg_persister.Add( *m_staggerRows, s_arrayOptions.m_GridStaggerRows );
181
182 m_cfg_persister.Add( *m_rbItemsRemainInPlace, s_arrayOptions.m_GridPositionItemsInPlace );
183 m_cfg_persister.Add( *m_rbCentreOnSource, s_arrayOptions.m_GridPositionCentreOnItems );
184
185 m_cfg_persister.Add( *m_cbRenumberPads, s_arrayOptions.m_GridRenumberPads );
188
190 m_cfg_persister.Add( *m_radioBoxGridNumberingScheme, s_arrayOptions.m_Grid2dArrayNumbering );
191 m_cfg_persister.Add( *m_choicePriAxisNumbering, s_arrayOptions.m_GridPrimaryAxisScheme );
192 m_cfg_persister.Add( *m_choiceSecAxisNumbering, s_arrayOptions.m_GridSecondaryAxisScheme );
193
194 m_cfg_persister.Add( *m_entryGridPriNumberingOffset, s_arrayOptions.m_GridPrimaryNumOffset );
195 m_cfg_persister.Add( *m_entryGridSecNumberingOffset, s_arrayOptions.m_GridSecondaryNumOffset );
196 m_cfg_persister.Add( *m_entryGridPriNumberingStep, s_arrayOptions.m_GridPrimaryAxisStep );
197 m_cfg_persister.Add( *m_entryGridSecNumberingStep, s_arrayOptions.m_GridSecondaryAxisStep );
198
199 // bind circular options to persister
200 m_cfg_persister.Add( m_hCentre, s_arrayOptions.m_CircCentreX );
201 m_cfg_persister.Add( m_vCentre, s_arrayOptions.m_CircCentreY );
202
203 m_cfg_persister.Add( *m_checkBoxFullCircle, s_arrayOptions.m_CircFullCircle );
204 m_cfg_persister.Add( m_circAngle, s_arrayOptions.m_CircAngle );
205 m_cfg_persister.Add( m_circOffset, s_arrayOptions.m_CircOffsetAngle );
206 m_cfg_persister.Add( *m_rbCircDirection, s_arrayOptions.m_CircleDirection );
208 m_cfg_persister.Add( *m_entryRotateItemsCb, s_arrayOptions.m_CircRotatationStep );
209
211 m_cfg_persister.Add( *m_choiceCircNumbering, s_arrayOptions.m_GridCircNumScheme );
212 m_cfg_persister.Add( *m_entryCircNumberingStart, s_arrayOptions.m_CircNumberingOffset );
213 m_cfg_persister.Add( *m_entryCircNumberingStep, s_arrayOptions.m_CircNumberingStep );
214
215 m_cfg_persister.Add( *m_gridTypeNotebook, s_arrayOptions.m_ArrayTypeTab );
216
218 m_cfg_persister.Add( *m_radioBtnDuplicateSelection, s_arrayOptions.m_SelectionDuplicate );
219
220 m_cfg_persister.Add( *m_radioBtnKeepRefs, s_arrayOptions.m_FootprintKeepAnnotations );
221 m_cfg_persister.Add( *m_radioBtnUniqueRefs, s_arrayOptions.m_FootprintReannotate );
222
223 m_cfg_persister.RestoreConfigToControls();
224
225 // Run the callbacks once to process the dialog contents
228
230 Fit();
231 SetMinSize( GetSize() );
232}
233
234
238
239
240void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
241{
242 if( m_checkBoxFullCircle->GetValue() && m_entryCircAngle == event.GetEventObject() )
243 {
244 return;
245 }
246
249}
250
251
252void DIALOG_CREATE_ARRAY::OnSelectCenterButton( wxCommandEvent& event )
253{
254 event.Skip();
255
256 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
257 PCB_PICKER_TOOL* pickerTool = toolMgr->GetTool<PCB_PICKER_TOOL>();
258 wxCHECK( pickerTool, /* void */ );
259
260 // Keep the dialog visible, but disable while picking.
261 // Hiding the dialog on GTK causes the controls to not accept their new values
262 Disable();
263
264 if( event.GetEventObject() == m_btnSelectCenterItem )
265 {
267 PCB_PICKER_TOOL::INTERACTIVE_PARAMS { this, _( "Select center item..." ) } );
268 }
269 else if( event.GetEventObject() == m_btnSelectCenterPoint )
270 {
272 PCB_PICKER_TOOL::INTERACTIVE_PARAMS { this, _( "Select center point..." ) } );
273 }
274 else
275 {
276 wxFAIL_MSG( "Unknown event source" );
277 }
278}
279
280
281void DIALOG_CREATE_ARRAY::OnAxisNumberingChange( wxCommandEvent& aEvent )
282{
283 // On an alphabet change, make sure the offset control is valid by default.
284
285 const int newAlphabet = aEvent.GetSelection();
286
287 wxCHECK( newAlphabet >= 0 && newAlphabet < static_cast<int>( numberingTypeData.size() ),
288 /* void */ );
289
290 const ARRAY_AXIS::NUMBERING_TYPE numberingType =
291 numberingTypeData[newAlphabet].m_numbering_type;
292
293 wxTextCtrl* matchingTextCtrl = nullptr;
294
295 if( aEvent.GetEventObject() == m_choicePriAxisNumbering )
296 matchingTextCtrl = m_entryGridPriNumberingOffset;
297 else if( aEvent.GetEventObject() == m_choiceSecAxisNumbering )
298 matchingTextCtrl = m_entryGridSecNumberingOffset;
299 else if( aEvent.GetEventObject() == m_choiceCircNumbering )
300 matchingTextCtrl = m_entryCircNumberingStart;
301
302 wxCHECK( matchingTextCtrl, /* void */ );
303
304 ARRAY_AXIS dummyAxis;
305 dummyAxis.SetAxisType( numberingType );
306
307 // If the text control has a valid value for the new alphabet, keep it
308 // else reset to the first value in the new alphabet.
309
310 const bool isAlreadyOK = dummyAxis.SetOffset( matchingTextCtrl->GetValue() );
311
312 if( !isAlreadyOK )
313 {
314 dummyAxis.SetOffset( ARRAY_AXIS::TypeIsNumeric( numberingType ) ? 1 : 0 );
315 matchingTextCtrl->SetValue( dummyAxis.GetItemNumber( 0 ) );
316 }
317}
318
319
320// Implement the RECEIVER interface for the callback from the TOOL
322{
323 if( aItem )
324 {
325 m_hCentre.SetValue( aItem->GetPosition().x );
326 m_vCentre.SetValue( aItem->GetPosition().y );
327 }
328
329 Enable( true );
330}
331
332
333void DIALOG_CREATE_ARRAY::UpdatePickedPoint( const std::optional<VECTOR2I>& aPoint )
334{
335 if( aPoint )
336 {
337 m_hCentre.SetValue( aPoint->x );
338 m_vCentre.SetValue( aPoint->y );
339 }
340
341 Enable( true );
342}
343
344
354static bool validateLongEntry( const wxTextEntry& entry, long& dest, const wxString& description,
355 wxArrayString& errors )
356{
357 bool ok = true;
358
359 if( !entry.GetValue().ToLong( &dest ) )
360 {
361 wxString err;
362 err.Printf( _( "Bad numeric value for %s: %s" ), description, entry.GetValue() );
363 errors.Add( err );
364 ok = false;
365 }
366
367 return ok;
368}
369
370
381static bool validateAxisOptions( const wxTextCtrl& offsetEntry, const wxChoice& typeEntry,
382 const wxTextCtrl& aStepEntry, ARRAY_AXIS& aAxis,
383 wxArrayString& errors )
384{
385 void* clientData = typeEntry.GetClientData( typeEntry.GetSelection() );
386 const NUMBERING_LIST_DATA* numberingData = static_cast<NUMBERING_LIST_DATA*>( clientData );
387
388 wxCHECK_MSG( numberingData, false, wxT( "Failed to get client data from list control." ) );
389
390 aAxis.SetAxisType( numberingData->m_numbering_type );
391
392 const wxString text = offsetEntry.GetValue();
393
394 bool ok = aAxis.SetOffset( text );
395
396 if( !ok )
397 {
398 errors.Add( wxString::Format( _( "Could not determine numbering start from '%s': "
399 "expected value consistent with alphabet '%s'." ),
400 text,
401 aAxis.GetAlphabet() ) );
402 return false;
403 }
404
405 long step;
406 ok = validateLongEntry( aStepEntry, step, _( "step value" ), errors );
407
408 if( ok )
409 aAxis.SetStep( step );
410
411 return ok;
412}
413
414
416{
417 std::unique_ptr<ARRAY_OPTIONS> newSettings;
418
419 wxArrayString errors;
420 const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
421
422 if( page == m_gridPanel )
423 {
424 auto newGrid = std::make_unique<ARRAY_GRID_OPTIONS>();
425 bool ok = true;
426
427 // ints
428 ok &= validateLongEntry(*m_entryNx, newGrid->m_nx, _("horizontal count"), errors);
429 ok &= validateLongEntry(*m_entryNy, newGrid->m_ny, _("vertical count"), errors);
430
431 newGrid->m_delta.x = m_hSpacing.GetIntValue();
432 newGrid->m_delta.y = m_vSpacing.GetIntValue();
433
434 if( ( newGrid->m_nx > 1 ) && ( newGrid->m_delta.x == 0 ) )
435 {
436 errors.Add( wxString::Format( _( "horizontal delta of zero with %ld objects" ), newGrid->m_nx ) );
437 ok = false;
438 }
439
440 if( ( newGrid->m_ny > 1 ) && ( newGrid->m_delta.y == 0 ) )
441 {
442 errors.Add( wxString::Format( _( "vertical delta of zero with %ld objects" ), newGrid->m_ny ) );
443 ok = false;
444 }
445
446 newGrid->m_offset.x = m_hOffset.GetIntValue();
447 newGrid->m_offset.y = m_vOffset.GetIntValue();
448
449 newGrid->m_centred = m_rbCentreOnSource->GetValue();
450
451 ok &= validateLongEntry(*m_entryStagger, newGrid->m_stagger, _("stagger"), errors);
452
453 newGrid->m_stagger_rows = m_staggerRows->GetValue();
454
455 newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
456 newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
457
458 newGrid->SetShouldNumber( m_isFootprintEditor && m_cbRenumberPads->GetValue() );
459
461 {
462 newGrid->SetNumberingStartIsSpecified( m_rbGridStartNumberingOpt->GetSelection() == 1 );
463
464 if( newGrid->GetNumberingStartIsSpecified() )
465 {
466 newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0;
467
468 // validate from the input fields
472 newGrid->m_pri_axis, errors );
473
474 if( newGrid->m_2dArrayNumbering )
475 {
479 newGrid->m_sec_axis, errors );
480 }
481
482 ok &= numOk;
483 }
484 else
485 {
486 // artificial linear numeric scheme from 1
487 newGrid->m_2dArrayNumbering = false;
488 newGrid->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
489 newGrid->m_pri_axis.SetOffset( 1 );
490 }
491 }
492
493 // Only use settings if all values are good
494 if( ok )
495 newSettings = std::move( newGrid );
496 }
497 else if( page == m_circularPanel )
498 {
499 auto newCirc = std::make_unique<ARRAY_CIRCULAR_OPTIONS>();
500 bool ok = true;
503
504 newCirc->m_centre.x = m_hCentre.GetIntValue();
505 newCirc->m_centre.y = m_vCentre.GetIntValue();
506 newCirc->m_angle = EDA_ANGLE( angle, DEGREES_T );
507 newCirc->m_angleOffset = EDA_ANGLE( offset, DEGREES_T );
508 newCirc->m_clockwise = m_rbCircDirection->GetSelection() == 0;
509
510 ok = validateLongEntry(*m_entryCircCount, newCirc->m_nPts, _("point count"), errors);
511
512 newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
513 newCirc->SetShouldNumber( m_isFootprintEditor );
514
515 if( ( newCirc->m_nPts > 1 ) && newCirc->m_angle.IsZero() )
516 {
517 errors.Add( wxString::Format( _( "angular delta of zero with %ld objects" ), newCirc->m_nPts ) );
518 ok = false;
519 }
520
522 {
523 newCirc->SetNumberingStartIsSpecified( m_rbCircStartNumberingOpt->GetSelection() == 1 );
524
525 if( newCirc->GetNumberingStartIsSpecified() )
526 {
528 *m_entryCircNumberingStep, newCirc->m_axis, errors );
529 }
530 else
531 {
532 // artificial linear numeric scheme from 1
533 newCirc->m_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
534 newCirc->m_axis.SetOffset( 1 ); // Start at "1"
535 }
536 }
537
538 // Only use settings if all values are good
539 if( ok )
540 newSettings = std::move( newCirc );
541 }
542
543 bool ret = false;
544
545 // If we got good settings, send them out and finish
546 if( newSettings )
547 {
548 // assign pointer and ownership here
549 m_settings = std::move( newSettings );
550
551 m_settings->SetShouldArrangeSelection( m_radioBtnArrangeSelection->GetValue() );
552 m_settings->SetSShouldReannotateFootprints( m_radioBtnUniqueRefs->GetValue() );
553
554 // persist the control state for next time
555 m_cfg_persister.ReadConfigFromControls();
556
557 ret = true;
558 }
559 else
560 {
561 wxString errorStr;
562
563 if( errors.IsEmpty() )
564 errorStr = _("Bad parameters");
565 else
566 errorStr = wxJoin( errors, '\n' );
567
568 wxMessageBox( errorStr );
569 ret = false;
570 }
571
572 // This dialog is not modal, so close it now if successful
573 if( ret )
574 Close();
575
576 return ret;
577}
578
579
581{
582 if( m_checkBoxFullCircle->GetValue() )
583 {
584 m_entryCircAngle->Disable();
585 }
586 else
587 {
588 m_entryCircAngle->Enable();
589 }
590
592 {
593 m_footprintReannotatePanel->Show( false );
594
595 m_gridPadNumberingPanel->Show( true );
596 m_circularPadNumberingPanel->Show( true );
597
598 // In no pad re-numbering, everything is disabled
599 bool renumber_pads = m_cbRenumberPads->GetValue();
600
601 m_radioBoxGridNumberingAxis->Enable( renumber_pads );
602 m_checkBoxGridReverseNumbering->Enable( renumber_pads );
603 m_rbGridStartNumberingOpt->Enable( renumber_pads );
604
605 // If we set the start number, we can set the other options,
606 // otherwise it's a hardcoded linear array
607 const bool use_set_start_grid = renumber_pads && m_rbGridStartNumberingOpt->GetSelection() == 1;
608
609 m_radioBoxGridNumberingScheme->Enable( use_set_start_grid );
610 m_labelPriAxisNumbering->Enable( use_set_start_grid );
611 m_choicePriAxisNumbering->Enable( use_set_start_grid );
612
613 // Disable the secondary axis numbering option if the
614 // numbering scheme doesn't have two axes
615 const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0;
616
617 m_labelSecAxisNumbering->Enable( use_set_start_grid && num2d );
618 m_choiceSecAxisNumbering->Enable( use_set_start_grid && num2d );
619
620 // We can only set an offset if we're setting the start number
621 m_labelGridNumberingOffset->Enable( use_set_start_grid );
622 m_labelGridNumberingStep->Enable( use_set_start_grid );
623 m_entryGridPriNumberingOffset->Enable( use_set_start_grid );
624 m_entryGridPriNumberingStep->Enable( use_set_start_grid );
625 m_entryGridSecNumberingOffset->Enable( use_set_start_grid && num2d );
626 m_entryGridSecNumberingStep->Enable( use_set_start_grid && num2d );
627
628 // disable the circular number offset in the same way
629 const bool use_set_start_circ = renumber_pads && m_rbCircStartNumberingOpt->GetSelection() == 1;
630 m_entryCircNumberingStart->Enable( use_set_start_circ );
631 }
632 else
633 {
634 // grid
635 m_rbGridStartNumberingOpt->Enable( false );
636 m_radioBoxGridNumberingScheme->Enable( false );
637
638 m_labelPriAxisNumbering->Enable( false );
639 m_labelSecAxisNumbering->Enable( false );
640
641 m_choiceSecAxisNumbering->Enable( false );
642 m_choicePriAxisNumbering->Enable( false );
643
644 m_labelGridNumberingOffset->Enable( false );
645 m_entryGridPriNumberingOffset->Enable( false );
646 m_entryGridSecNumberingOffset->Enable( false );
647
648 m_gridPadNumberingPanel->Show( false );
649
650 // circular
651 m_rbCircStartNumberingOpt->Enable( false );
652 m_entryCircNumberingStart->Enable( false );
653
654 m_circularPadNumberingPanel->Show( false );
655
656 m_footprintReannotatePanel->Show( true );
657 }
658
659 if( m_radioBtnArrangeSelection->GetValue() )
660 {
661 m_footprintReannotatePanel->Show( false );
662 }
663}
664
665
667{
668 // In full circle mode, the division angle is computed from the number of points
669 if( m_checkBoxFullCircle->GetValue() )
670 {
671 long nPts;
672 if( m_entryCircCount->GetValue().ToLong( &nPts ) )
673 {
674 EDA_ANGLE division = EDA_ANGLE( 360, DEGREES_T ) / nPts;
675 m_circAngle.SetAngleValue( division );
676 }
677 }
678}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
Class that contains information about a single array axis and the numbering of items along that axis.
Definition array_axis.h:40
bool SetOffset(const wxString &aOffsetName)
Set the axis start (as a string, which should decode to a valid index in the alphabet),...
wxString GetItemNumber(int n) const
Get the position number (name) for the n'th axis point.
static bool TypeIsNumeric(NUMBERING_TYPE type)
Check if a numbering type is a numeric type.
Definition array_axis.h:60
const wxString & GetAlphabet() const
Get the alphabet for the current numbering scheme.
void SetAxisType(NUMBERING_TYPE aType)
Set the axis numbering type.
@ NUMBERING_NUMERIC
Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11...
Definition array_axis.h:44
@ NUMBERING_ALPHA_NO_IOSQXZ
Alphabet, excluding IOSQXZ.
Definition array_axis.h:53
@ NUMBERING_ALPHA_FULL
Full 26-character alphabet.
Definition array_axis.h:54
void SetStep(int aStep)
Set the skip between consecutive numbers (useful when doing a partial array, e.g.
DIALOG_CREATE_ARRAY_BASE(wxWindow *parent, wxWindowID id=wxID_DIALOG_CREATE_ARRAY, const wxString &title=_("Create Array"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
WIDGET_SAVE_RESTORE m_cfg_persister
DIALOG_CREATE_ARRAY(PCB_BASE_FRAME *aParent, std::unique_ptr< ARRAY_OPTIONS > &aOptions, bool enableNumbering, const VECTOR2I &aOrigPos)
Construct a new dialog.
bool TransferDataFromWindow() override
PCB_BASE_FRAME * m_frame
void OnSelectCenterButton(wxCommandEvent &aEvent) override
const VECTOR2I m_originalItemPosition
std::unique_ptr< ARRAY_OPTIONS > & m_settings
The settings to re-seat on dialog OK.
void OnParameterChanged(wxCommandEvent &aEvent) override
void UpdatePickedItem(const EDA_ITEM *aItem) override
void UpdatePickedPoint(const std::optional< VECTOR2I > &aPoint) override
void OnAxisNumberingChange(wxCommandEvent &aEvent) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool Enable(bool enable) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
virtual VECTOR2I GetPosition() const
Definition eda_item.h:279
static TOOL_ACTION selectPointInteractively
static TOOL_ACTION selectItemInteractively
Selection of reference points/items.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
Generic tool for picking an item.
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
static const std::vector< NUMBERING_LIST_DATA > numberingTypeData
List of type <--> name mappings (in order) for the numbering type list boxes.
static bool validateAxisOptions(const wxTextCtrl &offsetEntry, const wxChoice &typeEntry, const wxTextCtrl &aStepEntry, ARRAY_AXIS &aAxis, wxArrayString &errors)
Validates and saves (if valid) the type and offset of an array axis numbering.
static bool validateLongEntry(const wxTextEntry &entry, long &dest, const wxString &description, wxArrayString &errors)
Validate and save a long integer entry.
static CREATE_ARRAY_DIALOG_ENTRIES s_arrayOptions
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
@ DEGREES_T
Definition eda_angle.h:31
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
Struct containing the last-entered values for the dialog.
CREATE_ARRAY_DIALOG_ENTRIES()
Construct with some sensible defaults.
Local mapping for list-box <-> numbering type.
ARRAY_AXIS::NUMBERING_TYPE m_numbering_type
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687