mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Recommendation is to avoid using the year nomenclature as this information is already encoded in the git repo. Avoids needing to repeatly update. Also updates AUTHORS.txt from current repo with contributor names
587 lines
21 KiB
C++
587 lines
21 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you may find one here:
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "dialogs/dialog_create_array.h"
|
|
|
|
#include <wx/msgdlg.h>
|
|
|
|
#include <base_units.h>
|
|
#include <footprint.h>
|
|
#include <pcb_edit_frame.h>
|
|
#include <tools/pcb_actions.h>
|
|
#include <tools/pcb_picker_tool.h>
|
|
#include <tool/tool_manager.h>
|
|
#include <widgets/text_ctrl_eval.h>
|
|
|
|
|
|
/**
|
|
* Struct containing the last-entered values for the dialog.
|
|
*/
|
|
struct CREATE_ARRAY_DIALOG_ENTRIES
|
|
{
|
|
/**
|
|
* Construct with some sensible defaults.
|
|
* In future, this could be loaded from config?
|
|
*/
|
|
CREATE_ARRAY_DIALOG_ENTRIES() {}
|
|
|
|
bool m_OptionsSet = true;
|
|
|
|
long m_GridNx = 5;
|
|
long m_GridNy = 5;
|
|
long m_GridDx = pcbIUScale.mmToIU( 2.54 );
|
|
long m_GridDy = pcbIUScale.mmToIU( 2.54 );
|
|
long m_GridOffsetX = 0;
|
|
long m_GridOffsetY = 0;
|
|
long m_GridStagger = 1;
|
|
bool m_GridStaggerRows = true;
|
|
bool m_GridPositionCentreOnItems = true;
|
|
long m_GridNumberingAxis = 0; // h then v
|
|
bool m_GridNumReverseAlt = false;
|
|
long m_GridNumStartSet = 1; // use specified start
|
|
long m_Grid2dArrayNumbering = 0; // linear numbering
|
|
long m_GridPrimaryAxisScheme = 0; // numeric
|
|
long m_GridSecondaryAxisScheme = 0; // numeric
|
|
wxString m_GridPrimaryNumOffset = wxT( "1" ); // numeric
|
|
wxString m_GridSecondaryNumOffset = wxT( "1" ); // numeric
|
|
long m_GridPrimaryAxisStep = 1;
|
|
long m_GridSecondaryAxisStep = 1;
|
|
|
|
long m_CircCentreX = 0;
|
|
long m_CircCentreY = 0;
|
|
EDA_ANGLE m_CircAngle = ANGLE_90;
|
|
long m_CircCount = 4;
|
|
bool m_CircFullCircle = 0;
|
|
long m_CircNumStartSet = 1; // use specified start
|
|
long m_GridCircNumScheme = 0;
|
|
wxString m_CircNumberingOffset = wxT("1");
|
|
long m_CircNumberingStep = 1;
|
|
bool m_CircRotatationStep = false;
|
|
long m_ArrayTypeTab = 0; // start on grid view
|
|
bool m_FootprintKeepAnnotations = false;
|
|
bool m_FootprintReannotate = true; // Assign unique by default
|
|
};
|
|
|
|
// Persistent options settings
|
|
static CREATE_ARRAY_DIALOG_ENTRIES s_arrayOptions;
|
|
|
|
/**
|
|
* Local mapping for list-box <-> numbering type
|
|
*/
|
|
struct NUMBERING_LIST_DATA
|
|
{
|
|
ARRAY_AXIS::NUMBERING_TYPE m_numbering_type;
|
|
wxString m_label;
|
|
};
|
|
|
|
/**
|
|
* List of type <--> name mappings (in order) for the numbering type
|
|
* list boxes
|
|
*/
|
|
static const std::vector<NUMBERING_LIST_DATA> numberingTypeData {
|
|
{
|
|
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC,
|
|
_( "Numerals (0,1,2,...,9,10)" ),
|
|
},
|
|
{
|
|
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_HEX,
|
|
_( "Hexadecimal (0,1,...,F,10,...)" ),
|
|
},
|
|
{
|
|
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_NO_IOSQXZ,
|
|
_( "Alphabet, minus IOSQXZ" ),
|
|
},
|
|
{
|
|
ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL,
|
|
_( "Alphabet, full 26 characters" ),
|
|
},
|
|
};
|
|
|
|
DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent,
|
|
std::unique_ptr<ARRAY_OPTIONS>& aSettings,
|
|
bool aIsFootprintEditor, const VECTOR2I& aOrigPos ) :
|
|
DIALOG_CREATE_ARRAY_BASE( aParent ),
|
|
m_frame( aParent ),
|
|
m_settings( aSettings ),
|
|
m_originalItemPosition( aOrigPos ), m_isFootprintEditor( aIsFootprintEditor ),
|
|
m_hSpacing( aParent, m_labelDx, m_entryDx, m_unitLabelDx ),
|
|
m_vSpacing( aParent, m_labelDy, m_entryDy, m_unitLabelDy ),
|
|
m_hOffset( aParent, m_labelOffsetX, m_entryOffsetX, m_unitLabelOffsetX ),
|
|
m_vOffset( aParent, m_labelOffsetY, m_entryOffsetY, m_unitLabelOffsetY ),
|
|
m_hCentre( aParent, m_labelCentreX, m_entryCentreX, m_unitLabelCentreX ),
|
|
m_vCentre( aParent, m_labelCentreY, m_entryCentreY, m_unitLabelCentreY ),
|
|
m_circAngle( aParent, m_labelCircAngle, m_entryCircAngle, m_unitLabelCircAngle ),
|
|
m_cfg_persister( pcbIUScale, s_arrayOptions.m_OptionsSet )
|
|
{
|
|
// Configure display origin transforms
|
|
m_hSpacing.SetCoordType( ORIGIN_TRANSFORMS::REL_X_COORD );
|
|
m_vSpacing.SetCoordType( ORIGIN_TRANSFORMS::REL_Y_COORD );
|
|
m_hOffset.SetCoordType( ORIGIN_TRANSFORMS::REL_X_COORD );
|
|
m_vOffset.SetCoordType( ORIGIN_TRANSFORMS::REL_Y_COORD );
|
|
m_hCentre.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
|
|
m_vCentre.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
|
|
|
|
// Set up numbering scheme drop downs character set strings
|
|
for( const auto& numData : numberingTypeData )
|
|
{
|
|
const wxString label = wxGetTranslation( numData.m_label );
|
|
void* clientData = (void*) &numData;
|
|
|
|
m_choicePriAxisNumbering->Append( label, clientData );
|
|
m_choiceSecAxisNumbering->Append( label, clientData );
|
|
m_choiceCircNumbering->Append( label, clientData );
|
|
}
|
|
|
|
m_choicePriAxisNumbering->SetSelection( 0 );
|
|
m_choiceSecAxisNumbering->SetSelection( 0 );
|
|
m_choiceCircNumbering->SetSelection( 0 );
|
|
|
|
m_circAngle.SetUnits( EDA_UNITS::DEGREES );
|
|
|
|
// bind grid options to persister
|
|
m_cfg_persister.Add( *m_entryNx, s_arrayOptions.m_GridNx );
|
|
m_cfg_persister.Add( *m_entryNy, s_arrayOptions.m_GridNy );
|
|
m_cfg_persister.Add( m_hSpacing, s_arrayOptions.m_GridDx );
|
|
m_cfg_persister.Add( m_vSpacing, s_arrayOptions.m_GridDy );
|
|
|
|
m_cfg_persister.Add( m_hOffset, s_arrayOptions.m_GridOffsetX );
|
|
m_cfg_persister.Add( m_vOffset, s_arrayOptions.m_GridOffsetY );
|
|
m_cfg_persister.Add( *m_entryStagger, s_arrayOptions.m_GridStagger );
|
|
|
|
m_cfg_persister.Add( *m_staggerRows, s_arrayOptions.m_GridStaggerRows );
|
|
|
|
m_cfg_persister.Add( *m_rbCentreOnSource, s_arrayOptions.m_GridPositionCentreOnItems );
|
|
|
|
m_cfg_persister.Add( *m_radioBoxGridNumberingAxis, s_arrayOptions.m_GridNumberingAxis );
|
|
m_cfg_persister.Add( *m_checkBoxGridReverseNumbering, s_arrayOptions.m_GridNumReverseAlt );
|
|
|
|
m_cfg_persister.Add( *m_rbGridStartNumberingOpt, s_arrayOptions.m_GridNumStartSet );
|
|
m_cfg_persister.Add( *m_radioBoxGridNumberingScheme, s_arrayOptions.m_Grid2dArrayNumbering );
|
|
m_cfg_persister.Add( *m_choicePriAxisNumbering, s_arrayOptions.m_GridPrimaryAxisScheme );
|
|
m_cfg_persister.Add( *m_choiceSecAxisNumbering, s_arrayOptions.m_GridSecondaryAxisScheme );
|
|
|
|
m_cfg_persister.Add( *m_entryGridPriNumberingOffset, s_arrayOptions.m_GridPrimaryNumOffset );
|
|
m_cfg_persister.Add( *m_entryGridSecNumberingOffset, s_arrayOptions.m_GridSecondaryNumOffset );
|
|
m_cfg_persister.Add( *m_entryGridPriNumberingStep, s_arrayOptions.m_GridPrimaryAxisStep );
|
|
m_cfg_persister.Add( *m_entryGridSecNumberingStep, s_arrayOptions.m_GridSecondaryAxisStep );
|
|
|
|
// bind circular options to persister
|
|
m_cfg_persister.Add( m_hCentre, s_arrayOptions.m_CircCentreX );
|
|
m_cfg_persister.Add( m_vCentre, s_arrayOptions.m_CircCentreY );
|
|
|
|
m_cfg_persister.Add( *m_checkBoxFullCircle, s_arrayOptions.m_CircFullCircle );
|
|
m_cfg_persister.Add( m_circAngle, s_arrayOptions.m_CircAngle );
|
|
m_cfg_persister.Add( *m_entryCircCount, s_arrayOptions.m_CircCount );
|
|
m_cfg_persister.Add( *m_entryRotateItemsCb, s_arrayOptions.m_CircRotatationStep );
|
|
|
|
m_cfg_persister.Add( *m_rbCircStartNumberingOpt, s_arrayOptions.m_CircNumStartSet );
|
|
m_cfg_persister.Add( *m_choiceCircNumbering, s_arrayOptions.m_GridCircNumScheme );
|
|
m_cfg_persister.Add( *m_entryCircNumberingStart, s_arrayOptions.m_CircNumberingOffset );
|
|
m_cfg_persister.Add( *m_entryCircNumberingStep, s_arrayOptions.m_CircNumberingStep );
|
|
|
|
m_cfg_persister.Add( *m_gridTypeNotebook, s_arrayOptions.m_ArrayTypeTab );
|
|
|
|
m_cfg_persister.Add( *m_radioBtnKeepRefs, s_arrayOptions.m_FootprintKeepAnnotations );
|
|
m_cfg_persister.Add( *m_radioBtnUniqueRefs, s_arrayOptions.m_FootprintReannotate );
|
|
|
|
m_cfg_persister.RestoreConfigToControls();
|
|
|
|
// Run the callbacks once to process the dialog contents
|
|
setControlEnablement();
|
|
calculateCircularArrayProperties();
|
|
|
|
SetupStandardButtons();
|
|
Fit();
|
|
SetMinSize( GetSize() );
|
|
}
|
|
|
|
|
|
DIALOG_CREATE_ARRAY::~DIALOG_CREATE_ARRAY()
|
|
{
|
|
}
|
|
|
|
|
|
void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
|
|
{
|
|
if( m_checkBoxFullCircle->GetValue() && m_entryCircAngle == event.GetEventObject() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
setControlEnablement();
|
|
calculateCircularArrayProperties();
|
|
}
|
|
|
|
|
|
void DIALOG_CREATE_ARRAY::OnSelectCenterButton( wxCommandEvent& event )
|
|
{
|
|
event.Skip();
|
|
|
|
PCB_PICKER_TOOL* pickerTool = m_frame->GetToolManager()->GetTool<PCB_PICKER_TOOL>();
|
|
wxCHECK( pickerTool, /* void */ );
|
|
|
|
if( event.GetEventObject() == m_btnSelectCenterItem )
|
|
{
|
|
m_frame->GetToolManager()->RunAction(
|
|
PCB_ACTIONS::selectItemInteractively,
|
|
PCB_PICKER_TOOL::INTERACTIVE_PARAMS{ this, _( "Select center item..." ) } );
|
|
}
|
|
else if( event.GetEventObject() == m_btnSelectCenterPoint )
|
|
{
|
|
m_frame->GetToolManager()->RunAction(
|
|
PCB_ACTIONS::selectPointInteractively,
|
|
PCB_PICKER_TOOL::INTERACTIVE_PARAMS{ this, _( "Select center point..." ) } );
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG( "Unknown event source" );
|
|
}
|
|
|
|
// Hide, but do not close, the dialog
|
|
Hide();
|
|
}
|
|
|
|
|
|
// Implement the RECEIVER interface for the callback from the TOOL
|
|
void DIALOG_CREATE_ARRAY::UpdatePickedItem( const EDA_ITEM* aItem )
|
|
{
|
|
if( aItem )
|
|
{
|
|
m_hCentre.SetValue( aItem->GetPosition().x );
|
|
m_vCentre.SetValue( aItem->GetPosition().y );
|
|
}
|
|
|
|
Show( true );
|
|
}
|
|
|
|
|
|
void DIALOG_CREATE_ARRAY::UpdatePickedPoint( const std::optional<VECTOR2I>& aPoint )
|
|
{
|
|
if( aPoint )
|
|
{
|
|
m_hCentre.SetValue( aPoint->x );
|
|
m_vCentre.SetValue( aPoint->y );
|
|
}
|
|
|
|
Show( true );
|
|
}
|
|
|
|
|
|
/**
|
|
* Validate and save a long integer entry
|
|
*
|
|
* @param entry the text entry to read from
|
|
* @param dest the value destination
|
|
* @param description description of the field (used if the value is not OK)
|
|
* @param errors a list of errors to add any error to
|
|
* @return valid
|
|
*/
|
|
static bool validateLongEntry( const wxTextEntry& entry, long& dest, const wxString& description,
|
|
wxArrayString& errors )
|
|
{
|
|
bool ok = true;
|
|
|
|
if( !entry.GetValue().ToLong( &dest ) )
|
|
{
|
|
wxString err;
|
|
err.Printf( _( "Bad numeric value for %s: %s" ), description, entry.GetValue() );
|
|
errors.Add( err );
|
|
ok = false;
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
/**
|
|
* Validates and saves (if valid) the type and offset of an array axis numbering
|
|
*
|
|
* @param offsetEntry the entry of the offset (text)
|
|
* @param typeEntry the entry of the axis nmbering scheme (choice)
|
|
* @param type the destination of the type if valid
|
|
* @param offset the destination of the offset if valid
|
|
* @param errors error string accumulator
|
|
* @return if all valid
|
|
*/
|
|
static bool validateAxisOptions( const wxTextCtrl& offsetEntry, const wxChoice& typeEntry,
|
|
const wxTextCtrl& aStepEntry, ARRAY_AXIS& aAxis,
|
|
wxArrayString& errors )
|
|
{
|
|
void* clientData = typeEntry.GetClientData( typeEntry.GetSelection() );
|
|
const NUMBERING_LIST_DATA* numberingData = static_cast<NUMBERING_LIST_DATA*>( clientData );
|
|
|
|
wxCHECK_MSG( numberingData, false, wxT( "Failed to get client data from list control." ) );
|
|
|
|
aAxis.SetAxisType( numberingData->m_numbering_type );
|
|
|
|
const wxString text = offsetEntry.GetValue();
|
|
|
|
bool ok = aAxis.SetOffset( text );
|
|
|
|
if( !ok )
|
|
{
|
|
errors.Add( wxString::Format( _( "Could not determine numbering start from '%s': "
|
|
"expected value consistent with alphabet '%s'." ),
|
|
text,
|
|
aAxis.GetAlphabet() ) );
|
|
return false;
|
|
}
|
|
|
|
long step;
|
|
ok = validateLongEntry( aStepEntry, step, _( "step value" ), errors );
|
|
|
|
if( ok )
|
|
aAxis.SetStep( step );
|
|
|
|
return ok;
|
|
}
|
|
|
|
|
|
bool DIALOG_CREATE_ARRAY::TransferDataFromWindow()
|
|
{
|
|
std::cout << "DIALOG_CREATE_ARRAY::TransferDataFromWindow()" << std::endl;
|
|
std::unique_ptr<ARRAY_OPTIONS> newSettings;
|
|
|
|
wxArrayString errors;
|
|
const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
|
|
|
|
if( page == m_gridPanel )
|
|
{
|
|
auto newGrid = std::make_unique<ARRAY_GRID_OPTIONS>();
|
|
bool ok = true;
|
|
|
|
// ints
|
|
ok &= validateLongEntry(*m_entryNx, newGrid->m_nx, _("horizontal count"), errors);
|
|
ok &= validateLongEntry(*m_entryNy, newGrid->m_ny, _("vertical count"), errors);
|
|
|
|
newGrid->m_delta.x = m_hSpacing.GetIntValue();
|
|
newGrid->m_delta.y = m_vSpacing.GetIntValue();
|
|
|
|
newGrid->m_offset.x = m_hOffset.GetIntValue();
|
|
newGrid->m_offset.y = m_vOffset.GetIntValue();
|
|
|
|
newGrid->m_centred = m_rbCentreOnSource->GetValue();
|
|
|
|
ok &= validateLongEntry(*m_entryStagger, newGrid->m_stagger, _("stagger"), errors);
|
|
|
|
newGrid->m_stagger_rows = m_staggerRows->GetValue();
|
|
|
|
newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
|
|
newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
|
|
|
|
newGrid->SetShouldNumber( m_isFootprintEditor );
|
|
|
|
if( m_isFootprintEditor )
|
|
{
|
|
newGrid->SetNumberingStartIsSpecified( m_rbGridStartNumberingOpt->GetSelection() == 1 );
|
|
|
|
if( newGrid->GetNumberingStartIsSpecified() )
|
|
{
|
|
newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
|
|
|
// validate from the input fields
|
|
bool numOk = validateAxisOptions( *m_entryGridPriNumberingOffset,
|
|
*m_choicePriAxisNumbering,
|
|
*m_entryGridPriNumberingStep,
|
|
newGrid->m_pri_axis, errors );
|
|
|
|
if( newGrid->m_2dArrayNumbering )
|
|
{
|
|
numOk &= validateAxisOptions( *m_entryGridSecNumberingOffset,
|
|
*m_choiceSecAxisNumbering,
|
|
*m_entryGridSecNumberingStep,
|
|
newGrid->m_sec_axis, errors );
|
|
}
|
|
|
|
ok &= numOk;
|
|
}
|
|
else
|
|
{
|
|
// artificial linear numeric scheme from 1
|
|
newGrid->m_2dArrayNumbering = false;
|
|
newGrid->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
|
|
newGrid->m_pri_axis.SetOffset( 1 );
|
|
}
|
|
}
|
|
|
|
// Only use settings if all values are good
|
|
if( ok )
|
|
newSettings = std::move( newGrid );
|
|
}
|
|
else if( page == m_circularPanel )
|
|
{
|
|
auto newCirc = std::make_unique<ARRAY_CIRCULAR_OPTIONS>();
|
|
bool ok = true;
|
|
double angle = EDA_UNIT_UTILS::UI::DoubleValueFromString( m_entryCircAngle->GetValue() );
|
|
|
|
newCirc->m_centre.x = m_hCentre.GetIntValue();
|
|
newCirc->m_centre.y = m_vCentre.GetIntValue();
|
|
newCirc->m_angle = EDA_ANGLE( angle, DEGREES_T );
|
|
|
|
ok = validateLongEntry(*m_entryCircCount, newCirc->m_nPts, _("point count"), errors);
|
|
|
|
newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
|
|
newCirc->SetShouldNumber( m_isFootprintEditor );
|
|
|
|
if( m_isFootprintEditor )
|
|
{
|
|
newCirc->SetNumberingStartIsSpecified( m_rbCircStartNumberingOpt->GetSelection() == 1 );
|
|
|
|
if( newCirc->GetNumberingStartIsSpecified() )
|
|
{
|
|
ok &= validateAxisOptions( *m_entryCircNumberingStart, *m_choiceCircNumbering,
|
|
*m_entryCircNumberingStep, newCirc->m_axis, errors );
|
|
}
|
|
else
|
|
{
|
|
// artificial linear numeric scheme from 1
|
|
newCirc->m_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC );
|
|
newCirc->m_axis.SetOffset( 1 ); // Start at "1"
|
|
}
|
|
}
|
|
|
|
// Only use settings if all values are good
|
|
if( ok )
|
|
newSettings = std::move( newCirc );
|
|
}
|
|
|
|
bool ret = false;
|
|
|
|
// If we got good settings, send them out and finish
|
|
if( newSettings )
|
|
{
|
|
// assign pointer and ownership here
|
|
m_settings = std::move( newSettings );
|
|
|
|
m_settings->SetSShouldReannotateFootprints( m_radioBtnUniqueRefs->GetValue() );
|
|
|
|
// persist the control state for next time
|
|
m_cfg_persister.ReadConfigFromControls();
|
|
|
|
ret = true;
|
|
}
|
|
else
|
|
{
|
|
wxString errorStr;
|
|
|
|
if( errors.IsEmpty() )
|
|
errorStr = _("Bad parameters");
|
|
else
|
|
errorStr = wxJoin( errors, '\n' );
|
|
|
|
wxMessageBox( errorStr );
|
|
ret = false;
|
|
}
|
|
|
|
// This dialog is not modal, so close it now
|
|
Close();
|
|
return ret;
|
|
}
|
|
|
|
|
|
void DIALOG_CREATE_ARRAY::setControlEnablement()
|
|
{
|
|
if( m_checkBoxFullCircle->GetValue() )
|
|
{
|
|
m_entryCircAngle->Disable();
|
|
}
|
|
else
|
|
{
|
|
m_entryCircAngle->Enable();
|
|
}
|
|
|
|
if( m_isFootprintEditor )
|
|
{
|
|
m_footprintReannotatePanel->Show( false );
|
|
|
|
m_gridPadNumberingPanel->Show( true );
|
|
m_circularPadNumberingPanel->Show( true );
|
|
|
|
// If we set the start number, we can set the other options,
|
|
// otherwise it's a hardcoded linear array
|
|
const bool use_set_start_grid = m_rbGridStartNumberingOpt->GetSelection() == 1;
|
|
|
|
m_radioBoxGridNumberingScheme->Enable( use_set_start_grid );
|
|
m_labelPriAxisNumbering->Enable( use_set_start_grid );
|
|
m_choicePriAxisNumbering->Enable( use_set_start_grid );
|
|
|
|
// Disable the secondary axis numbering option if the
|
|
// numbering scheme doesn't have two axes
|
|
const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0;
|
|
|
|
m_labelSecAxisNumbering->Enable( use_set_start_grid && num2d );
|
|
m_choiceSecAxisNumbering->Enable( use_set_start_grid && num2d );
|
|
|
|
// We can only set an offset if we're setting the start number
|
|
m_labelGridNumberingOffset->Enable( use_set_start_grid );
|
|
m_entryGridPriNumberingOffset->Enable( use_set_start_grid );
|
|
m_entryGridSecNumberingOffset->Enable( use_set_start_grid && num2d );
|
|
m_entryGridSecNumberingStep->Enable( use_set_start_grid && num2d );
|
|
|
|
// disable the circular number offset in the same way
|
|
const bool use_set_start_circ = m_rbCircStartNumberingOpt->GetSelection() == 1;
|
|
m_entryCircNumberingStart->Enable( use_set_start_circ );
|
|
}
|
|
else
|
|
{
|
|
// grid
|
|
m_rbGridStartNumberingOpt->Enable( false );
|
|
m_radioBoxGridNumberingScheme->Enable( false );
|
|
|
|
m_labelPriAxisNumbering->Enable( false );
|
|
m_labelSecAxisNumbering->Enable( false );
|
|
|
|
m_choiceSecAxisNumbering->Enable( false );
|
|
m_choicePriAxisNumbering->Enable( false );
|
|
|
|
m_labelGridNumberingOffset->Enable( false );
|
|
m_entryGridPriNumberingOffset->Enable( false );
|
|
m_entryGridSecNumberingOffset->Enable( false );
|
|
|
|
m_gridPadNumberingPanel->Show( false );
|
|
|
|
// circular
|
|
m_rbCircStartNumberingOpt->Enable( false );
|
|
m_entryCircNumberingStart->Enable( false );
|
|
|
|
m_circularPadNumberingPanel->Show( false );
|
|
|
|
m_footprintReannotatePanel->Show( true );
|
|
}
|
|
}
|
|
|
|
|
|
void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
|
|
{
|
|
// In full circle mode, the division angle is computed from the number of points
|
|
if( m_checkBoxFullCircle->GetValue() )
|
|
{
|
|
long nPts;
|
|
if( m_entryCircCount->GetValue().ToLong( &nPts ) )
|
|
{
|
|
EDA_ANGLE division = EDA_ANGLE( 360, DEGREES_T ) / nPts;
|
|
m_circAngle.SetAngleValue( division );
|
|
}
|
|
}
|
|
}
|