diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index cd9f38f4cb..020124b648 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -280,6 +280,7 @@ set( COMMON_SRCS ${COMMON_PREVIEW_ITEMS_SRCS} ${PLOTTERS_CONTROL_SRCS} advanced_config.cpp + array_axis.cpp array_options.cpp base_struct.cpp bezier_curves.cpp diff --git a/common/array_axis.cpp b/common/array_axis.cpp new file mode 100644 index 0000000000..8737f7b62c --- /dev/null +++ b/common/array_axis.cpp @@ -0,0 +1,153 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019 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 <array_axis.h> + + +/** + * @return False for schemes like 0,1...9,10 + * True for schemes like A,B..Z,AA (where the tens column starts with char 0) + */ +static bool schemeNonUnitColsStartAt0( ARRAY_AXIS::NUMBERING_TYPE type ) +{ + return type == ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL + || type == ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_NO_IOSQXZ; +} + + +ARRAY_AXIS::ARRAY_AXIS() : m_type( NUMBERING_TYPE::NUMBERING_NUMERIC ), m_offset( 0 ) +{ +} + + +const wxString& ARRAY_AXIS::GetAlphabet() const +{ + static const wxString alphaNumeric = "0123456789"; + static const wxString alphaHex = "0123456789ABCDEF"; + static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY"; + + switch( m_type ) + { + default: + case NUMBERING_NUMERIC: + return alphaNumeric; + case NUMBERING_HEX: + return alphaHex; + case NUMBERING_ALPHA_NO_IOSQXZ: + return alphaNoIOSQXZ; + case NUMBERING_ALPHA_FULL: + return alphaFull; + } +} + + +OPT<int> ARRAY_AXIS::getNumberingOffset( const wxString& str ) const +{ + if( str.length() == 0 ) + return OPT<int>{}; + + const wxString& alphabet = GetAlphabet(); + + int offset = 0; + const int radix = alphabet.length(); + + for( unsigned i = 0; i < str.length(); i++ ) + { + int chIndex = alphabet.Find( str[i], false ); + + if( chIndex == wxNOT_FOUND ) + return OPT<int>{}; + + const bool start0 = schemeNonUnitColsStartAt0( m_type ); + + // eg "AA" is actually index 27, not 26 + if( start0 && i < str.length() - 1 ) + chIndex++; + + offset *= radix; + offset += chIndex; + } + + return OPT<int>{ offset }; +} + + +void ARRAY_AXIS::SetAxisType( NUMBERING_TYPE aType ) +{ + m_type = aType; +} + + +bool ARRAY_AXIS::SetOffset( const wxString& aOffsetName ) +{ + OPT<int> offset = getNumberingOffset( aOffsetName ); + + // The string does not decode to a valid offset + if( !offset ) + return false; + + SetOffset( *offset ); + return true; +} + + +void ARRAY_AXIS::SetOffset( int aOffset ) +{ + m_offset = aOffset; +} + + +int ARRAY_AXIS::GetOffset() const +{ + return m_offset; +} + + +wxString ARRAY_AXIS::GetItemNumber( int n ) const +{ + wxString itemNum; + const wxString& alphabet = GetAlphabet(); + + const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( m_type ); + + bool firstRound = true; + int radix = alphabet.Length(); + + n += m_offset; + + do + { + int modN = n % radix; + + if( nonUnitColsStartAt0 && !firstRound ) + modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx" + + itemNum.insert( 0, 1, alphabet[modN] ); + + n /= radix; + firstRound = false; + } while( n ); + + return itemNum; +} \ No newline at end of file diff --git a/common/array_options.cpp b/common/array_options.cpp index 8a2faa4e84..d2e9dd605d 100644 --- a/common/array_options.cpp +++ b/common/array_options.cpp @@ -25,86 +25,6 @@ #include <trigo.h> -const wxString& ARRAY_OPTIONS::AlphabetFromNumberingScheme( NUMBERING_TYPE_T type ) -{ - static const wxString alphaNumeric = "0123456789"; - static const wxString alphaHex = "0123456789ABCDEF"; - static const wxString alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - static const wxString alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY"; - - switch( type ) - { - default: - case NUMBERING_NUMERIC: return alphaNumeric; - case NUMBERING_HEX: return alphaHex; - case NUMBERING_ALPHA_NO_IOSQXZ: return alphaNoIOSQXZ; - case NUMBERING_ALPHA_FULL: return alphaFull; - } -} - - -bool ARRAY_OPTIONS::SchemeNonUnitColsStartAt0( NUMBERING_TYPE_T type ) -{ - return type == NUMBERING_ALPHA_FULL || type == NUMBERING_ALPHA_NO_IOSQXZ; -} - - -bool ARRAY_OPTIONS::GetNumberingOffset( - const wxString& str, ARRAY_OPTIONS::NUMBERING_TYPE_T type, int& offsetToFill ) -{ - const wxString& alphabet = ARRAY_OPTIONS::AlphabetFromNumberingScheme( type ); - - int offset = 0; - const int radix = alphabet.length(); - - for( unsigned i = 0; i < str.length(); i++ ) - { - int chIndex = alphabet.Find( str[i], false ); - - if( chIndex == wxNOT_FOUND ) - return false; - - const bool start0 = ARRAY_OPTIONS::SchemeNonUnitColsStartAt0( type ); - - // eg "AA" is actually index 27, not 26 - if( start0 && i < str.length() - 1 ) - chIndex++; - - offset *= radix; - offset += chIndex; - } - - offsetToFill = offset; - return true; -} - - -wxString ARRAY_OPTIONS::getCoordinateNumber( int n, NUMBERING_TYPE_T type ) -{ - wxString itemNum; - const wxString& alphabet = AlphabetFromNumberingScheme( type ); - - const bool nonUnitColsStartAt0 = SchemeNonUnitColsStartAt0( type ); - - bool firstRound = true; - int radix = alphabet.Length(); - - do - { - int modN = n % radix; - - if( nonUnitColsStartAt0 && !firstRound ) - modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx" - - itemNum.insert( 0, 1, alphabet[modN] ); - - n /= radix; - firstRound = false; - } while( n ); - - return itemNum; -} - int ARRAY_GRID_OPTIONS::GetArraySize() const { @@ -167,12 +87,12 @@ wxString ARRAY_GRID_OPTIONS::GetItemNumber( int n ) const { VECTOR2I coords = getGridCoords( n ); - itemNum += getCoordinateNumber( coords.x + m_numberingOffsetX, m_priAxisNumType ); - itemNum += getCoordinateNumber( coords.y + m_numberingOffsetY, m_secAxisNumType ); + itemNum << m_pri_axis.GetItemNumber( coords.x ); + itemNum << m_sec_axis.GetItemNumber( coords.y ); } else { - itemNum += getCoordinateNumber( n + m_numberingOffsetX, m_priAxisNumType ); + itemNum << m_pri_axis.GetItemNumber( n ); } return itemNum; @@ -209,5 +129,5 @@ ARRAY_OPTIONS::TRANSFORM ARRAY_CIRCULAR_OPTIONS::GetTransform( int n, const VECT wxString ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const { - return getCoordinateNumber( aN + m_numberingOffset, m_numberingType ); + return m_axis.GetItemNumber( aN ); } diff --git a/include/array_axis.h b/include/array_axis.h new file mode 100644 index 0000000000..49388b2f95 --- /dev/null +++ b/include/array_axis.h @@ -0,0 +1,110 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019 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 + */ + +#ifndef ARRAY_AXIS__H +#define ARRAY_AXIS__H + +#include <core/optional.h> + +#include <wx/string.h> + +/** + * Class that contains information about a single array axis and the numbering + * of items along that axis. + * + * For example, a rectangular grid has two axes, X and Y, but a circular array + * has only one, that runs around the circle. + */ +class ARRAY_AXIS +{ +public: + enum NUMBERING_TYPE + { + NUMBERING_NUMERIC = 0, ///< Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11... + NUMBERING_HEX, + NUMBERING_ALPHA_NO_IOSQXZ, /*!< Alphabet, excluding IOSQXZ + * + * Per ASME Y14.35M-1997 sec. 5.2 (previously MIL-STD-100 sec. 406.5) + * as these can be confused with numerals and are often not used + * for pin numbering on BGAs, etc + */ + NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet + }; + + ARRAY_AXIS(); + + /** + * Get the alphabet for the current numbering scheme. + * @param type the numbering scheme + * @return the alphabet (as a string) + */ + const wxString& GetAlphabet() const; + + /** + * Set the axis numbering type + */ + void SetAxisType( NUMBERING_TYPE aType ); + + /** + * Set the axis start (as a string, which should decode to a valid index + * in the alphabet) + */ + bool SetOffset( const wxString& aOffsetName ); + + /** + * Set the start offset for the series (e.g. 0 to start at 0/A, 4 to start + * at 4/E). + * + * @param aOffset offset of the first item in the + */ + void SetOffset( int aOffset ); + + /** + * Get the numbering offset for the axis + * + * @return the current offset + */ + int GetOffset() const; + + /** + * Get the position number (name) for the n'th axis point + * + * @param n array point index, from 0 + * @return the point's name + */ + wxString GetItemNumber( int n ) const; + +private: + /** + * Get the numbering offset for a given numbering string + * + * @param str a numbering string, say "B" or "5" + * @return the offset, if found, else empty + */ + OPT<int> getNumberingOffset( const wxString& str ) const; + + NUMBERING_TYPE m_type; + int m_offset; +}; + +#endif // ARRAY_AXIS__H \ No newline at end of file diff --git a/include/array_options.h b/include/array_options.h index 8be7d5ccf5..fb758df0ec 100644 --- a/include/array_options.h +++ b/include/array_options.h @@ -26,6 +26,8 @@ #include <math/vector2d.h> +#include <array_axis.h> + /** * Options that govern the setup of an "array" of multiple item. * The base #ARRAY_OPTIONS do not encode a specific geometry or numbering @@ -40,20 +42,6 @@ public: ARRAY_CIRCULAR, ///< A circular array }; - // NOTE: do not change order relative to charSetDescriptions - enum NUMBERING_TYPE_T - { - NUMBERING_NUMERIC = 0, ///< Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11... - NUMBERING_HEX, - NUMBERING_ALPHA_NO_IOSQXZ, /*!< Alphabet, excluding IOSQXZ - * - * Per ASME Y14.35M-1997 sec. 5.2 (previously MIL-STD-100 sec. 406.5) - * as these can be confused with numerals and are often not used - * for pin numbering on BGAs, etc - */ - NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet - }; - ARRAY_OPTIONS( ARRAY_TYPE_T aType ) : m_type( aType ), m_shouldNumber( false ), m_numberingStartIsSpecified( false ) { @@ -61,29 +49,6 @@ public: virtual ~ARRAY_OPTIONS(){}; - /** - * Get the alphabet for a particular numbering scheme. - * @param type the numbering scheme - * @return the alphabet (as a string) - */ - static const wxString& AlphabetFromNumberingScheme( NUMBERING_TYPE_T type ); - - /** - * @return False for schemes like 0,1...9,10 - * True for schemes like A,B..Z,AA (where the tens column starts with char 0) - */ - static bool SchemeNonUnitColsStartAt0( NUMBERING_TYPE_T type ); - - /** - * Get the numbering offset for a given numbering string - * @param str a numbering string, say "B" or "5" - * @param type the type this string should be - * @param offsetToFill the offset to set, if found - * @return true if the string is a valid offset of this type - */ - static bool GetNumberingOffset( - const wxString& str, ARRAY_OPTIONS::NUMBERING_TYPE_T type, int& offsetToFill ); - /** * Transform applied to an object by this array */ @@ -143,7 +108,6 @@ public: } protected: - static wxString getCoordinateNumber( int n, NUMBERING_TYPE_T type ); ARRAY_TYPE_T m_type; @@ -166,11 +130,7 @@ struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS m_reverseNumberingAlternate( false ), m_stagger( 0 ), m_stagger_rows( true ), - m_2dArrayNumbering( false ), - m_numberingOffsetX( 0 ), - m_numberingOffsetY( 0 ), - m_priAxisNumType( NUMBERING_NUMERIC ), - m_secAxisNumType( NUMBERING_NUMERIC ) + m_2dArrayNumbering( false ) { } @@ -181,8 +141,7 @@ struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS long m_stagger; bool m_stagger_rows; bool m_2dArrayNumbering; - int m_numberingOffsetX, m_numberingOffsetY; - NUMBERING_TYPE_T m_priAxisNumType, m_secAxisNumType; + ARRAY_AXIS m_pri_axis, m_sec_axis; TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override; int GetArraySize() const override; @@ -199,9 +158,7 @@ struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS : ARRAY_OPTIONS( ARRAY_CIRCULAR ), m_nPts( 0 ), m_angle( 0.0f ), - m_rotateItems( false ), - m_numberingType( NUMBERING_NUMERIC ), - m_numberingOffset( 0 ) + m_rotateItems( false ) { } @@ -211,8 +168,7 @@ struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS double m_angle; VECTOR2I m_centre; bool m_rotateItems; - NUMBERING_TYPE_T m_numberingType; - long m_numberingOffset; + ARRAY_AXIS m_axis; TRANSFORM GetTransform( int aN, const VECTOR2I& aPos ) const override; int GetArraySize() const override; diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp index f96e5b2162..ed9b0b3fb7 100644 --- a/pcbnew/dialogs/dialog_create_array.cpp +++ b/pcbnew/dialogs/dialog_create_array.cpp @@ -114,7 +114,7 @@ DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( // Set up numbering scheme drop downs // // character set - // NOTE: do not change the order of this relative to the NUMBERING_TYPE_T enum + // NOTE: do not change the order of this relative to the NUMBERING_TYPE enum const wxString charSetDescriptions[] = { _( "Numerals (0,1,2,...,9,10)" ), @@ -206,17 +206,15 @@ void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event ) * @return if all valid */ static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry, - const wxChoice& typeEntry, - ARRAY_OPTIONS::NUMBERING_TYPE_T& type, - int& offset, wxArrayString& errors ) + const wxChoice& typeEntry, ARRAY_AXIS& aAxis, wxArrayString& errors ) { const int typeVal = typeEntry.GetSelection(); // mind undefined casts to enums (should not be able to happen) - bool ok = typeVal <= ARRAY_OPTIONS::NUMBERING_TYPE_MAX; + bool ok = typeVal <= ARRAY_AXIS::NUMBERING_TYPE_MAX; if( ok ) { - type = (ARRAY_OPTIONS::NUMBERING_TYPE_T) typeVal; + aAxis.SetAxisType( static_cast<ARRAY_AXIS::NUMBERING_TYPE>( typeVal ) ); } else { @@ -228,17 +226,19 @@ static bool validateNumberingTypeAndOffset( const wxTextCtrl& offsetEntry, } const wxString text = offsetEntry.GetValue(); - ok = ARRAY_OPTIONS::GetNumberingOffset( text, type, offset ); + + ok = aAxis.SetOffset( text ); if( !ok ) { - const wxString& alphabet = ARRAY_OPTIONS::AlphabetFromNumberingScheme( type ); + const wxString& alphabet = aAxis.GetAlphabet(); wxString err; err.Printf( _( "Could not determine numbering start from \"%s\": " "expected value consistent with alphabet \"%s\"" ), text, alphabet ); errors.Add(err); + return false; } return ok; @@ -311,14 +311,12 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow() // validate from the input fields bool numOk = validateNumberingTypeAndOffset( *m_entryGridPriNumberingOffset, - *m_choicePriAxisNumbering, newGrid->m_priAxisNumType, - newGrid->m_numberingOffsetX, errors ); + *m_choicePriAxisNumbering, newGrid->m_pri_axis, errors ); if( newGrid->m_2dArrayNumbering ) { numOk = validateNumberingTypeAndOffset( *m_entryGridSecNumberingOffset, - *m_choiceSecAxisNumbering, newGrid->m_secAxisNumType, - newGrid->m_numberingOffsetY, errors ) + *m_choiceSecAxisNumbering, newGrid->m_sec_axis, errors ) && numOk; } @@ -328,8 +326,8 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow() { // artificial linear numeric scheme from 1 newGrid->m_2dArrayNumbering = false; - newGrid->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; - newGrid->m_numberingOffsetX = 1; // Start at "1" + newGrid->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC ); + newGrid->m_pri_axis.SetOffset( 1 ); } } @@ -359,16 +357,23 @@ bool DIALOG_CREATE_ARRAY::TransferDataFromWindow() if( newCirc->GetNumberingStartIsSpecified() ) { - newCirc->m_numberingType = ARRAY_OPTIONS::NUMBERING_NUMERIC; + newCirc->m_axis.SetAxisType( ARRAY_AXIS::NUMBERING_NUMERIC ); + + long offset; ok = ok - && validateLongEntry( *m_entryCircNumberingStart, newCirc->m_numberingOffset, - _( "numbering start" ), errors ); + && validateLongEntry( + *m_entryCircNumberingStart, offset, _( "numbering start" ), errors ); + + if( ok ) + { + newCirc->m_axis.SetOffset( offset ); + } } else { // artificial linear numeric scheme from 1 - newCirc->m_numberingOffset = 1; // Start at "1" + newCirc->m_axis.SetOffset( 1 ); // Start at "1" } } diff --git a/qa/common/CMakeLists.txt b/qa/common/CMakeLists.txt index dc9ac1d1c4..5f8e4b67c9 100644 --- a/qa/common/CMakeLists.txt +++ b/qa/common/CMakeLists.txt @@ -36,6 +36,7 @@ set( common_srcs ../../common/colors.cpp ../../common/observable.cpp + test_array_axis.cpp test_array_options.cpp test_color4d.cpp test_coroutine.cpp diff --git a/qa/common/test_array_axis.cpp b/qa/common/test_array_axis.cpp new file mode 100644 index 0000000000..baf5b62174 --- /dev/null +++ b/qa/common/test_array_axis.cpp @@ -0,0 +1,209 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019 KiCad Developers, see CHANGELOG.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 + */ + +/** + * @file + * Test suite for #ARRAY_AXIS + */ + +#include <unit_test_utils/unit_test_utils.h> + +#include <array_axis.h> + +/** + * Declare the test suite + */ +BOOST_AUTO_TEST_SUITE( ArrayAxis ) + +struct VALID_OFFSET_CASE +{ + ARRAY_AXIS::NUMBERING_TYPE m_axis_type; + std::string m_offset_str; + bool m_exp_valid; + int m_exp_offset; +}; + + +/** + * Check we can get valid (or invalid) offsets as expected + */ +BOOST_AUTO_TEST_CASE( ValidOffsets ) +{ + // clang-format off + const std::vector<VALID_OFFSET_CASE> cases = { + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "0", + true, + 0, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "1", + true, + 1, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "1234", + true, + 1234, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "", + false, + 0, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "www", + false, + 0, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, + "A", + true, + 0, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, + "XY", + true, + 648, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_HEX, + "A0", + true, + 160, + }, + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_HEX, + "G0", + false, + 0, + }, + }; + // clang-format on + + for( const auto& c : cases ) + { + ARRAY_AXIS axis; + axis.SetAxisType( c.m_axis_type ); + + bool offset_ok = axis.SetOffset( c.m_offset_str ); + + BOOST_CHECK_EQUAL( offset_ok, c.m_exp_valid ); + + if( c.m_exp_valid ) + { + BOOST_CHECK_EQUAL( axis.GetOffset(), c.m_exp_offset ); + } + } +} + +/** + * Data for testing a single array axis + */ +struct ARRAY_AXIS_NAMING_PARAMS +{ + ARRAY_AXIS::NUMBERING_TYPE m_axis_type; + std::string m_start_at; +}; + +struct ARRAY_AXIS_NAMING_CASE +{ + std::string m_case_name; + ARRAY_AXIS_NAMING_PARAMS m_prms; + int m_num; + std::vector<std::string> m_exp_names; +}; + + +// clang-format off +static const std::vector<ARRAY_AXIS_NAMING_CASE> axis_name_cases = { + { + "Linear", + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + "1", + }, + 6, + { "1", "2", "3", "4", "5", "6" }, + }, + { + // Test alphabetical + "Alpha", + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, + "A", + }, + 3, + { "A", "B", "C" }, + }, + { + // Test alphabetical with 2nd col + "Alpha 2nd col", + { + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, + "Y", + }, + 4, + { "Y", "Z", "AA", "AB" }, + }, +}; +// clang-format on + +/** + * Test of the naming cases + */ +BOOST_AUTO_TEST_CASE( Numbering ) +{ + for( const auto& c : axis_name_cases ) + { + BOOST_TEST_CONTEXT( c.m_case_name ) + { + ARRAY_AXIS axis; + axis.SetAxisType( c.m_prms.m_axis_type ); + + bool start_ok = axis.SetOffset( c.m_prms.m_start_at ); + + // All these examples have valid start offsets + BOOST_CHECK( start_ok ); + + std::vector<std::string> names; + + for( int i = 0; i < c.m_num; i++ ) + { + names.push_back( axis.GetItemNumber( i ).ToStdString() ); + } + + BOOST_CHECK_EQUAL_COLLECTIONS( + names.begin(), names.end(), c.m_exp_names.begin(), c.m_exp_names.end() ); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/qa/common/test_array_options.cpp b/qa/common/test_array_options.cpp index cfb510d554..b72cf76f32 100644 --- a/qa/common/test_array_options.cpp +++ b/qa/common/test_array_options.cpp @@ -392,14 +392,14 @@ void CheckArrayNumbering( const ARRAY_OPTIONS& aOpts, const std::vector<std::str struct GRID_ARRAY_NAMING_PARAMS { - ARRAY_OPTIONS::NUMBERING_TYPE_T m_pri_type; - ARRAY_OPTIONS::NUMBERING_TYPE_T m_sec_type; - std::string m_start_at_x; - std::string m_start_at_y; - bool m_2d_numbering; - bool m_h_then_v; - int m_nx; - int m_ny; + ARRAY_AXIS::NUMBERING_TYPE m_pri_type; + ARRAY_AXIS::NUMBERING_TYPE m_sec_type; + std::string m_start_at_x; + std::string m_start_at_y; + bool m_2d_numbering; + bool m_h_then_v; + int m_nx; + int m_ny; }; @@ -416,8 +416,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = { { "Linear grid", { - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, // doesn't matter here + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, // doesn't matter here "1", "2", false, @@ -431,8 +431,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = { // Tests a 2d grid "2D grid A1", { - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_ALPHA_FULL, - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, "A", "1", true, @@ -446,8 +446,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = { // Tests a 2d grid "2D grid 11", { - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, "1", "1", true, @@ -463,8 +463,8 @@ static const std::vector<GRID_ARRAY_NAMING_CASE> grid_name_cases = { // Tests a 2d grid, with different types and offsets (and alphabet wrap) "2D grid offsets", { - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC, - ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_ALPHA_FULL, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC, + ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_ALPHA_FULL, "5", "Z", true, @@ -494,13 +494,11 @@ BOOST_AUTO_TEST_CASE( GridNaming ) grid_opts.m_horizontalThenVertical = c.m_prms.m_h_then_v; - ARRAY_OPTIONS::GetNumberingOffset( - c.m_prms.m_start_at_x, c.m_prms.m_pri_type, grid_opts.m_numberingOffsetX ); - ARRAY_OPTIONS::GetNumberingOffset( - c.m_prms.m_start_at_y, c.m_prms.m_sec_type, grid_opts.m_numberingOffsetY ); + grid_opts.m_pri_axis.SetAxisType( c.m_prms.m_pri_type ); + grid_opts.m_sec_axis.SetAxisType( c.m_prms.m_sec_type ); - grid_opts.m_priAxisNumType = c.m_prms.m_pri_type; - grid_opts.m_secAxisNumType = c.m_prms.m_sec_type; + grid_opts.m_pri_axis.SetOffset( c.m_prms.m_start_at_x ); + grid_opts.m_sec_axis.SetOffset( c.m_prms.m_start_at_y ); grid_opts.m_2dArrayNumbering = c.m_prms.m_2d_numbering; diff --git a/qa/pcbnew/test_array_pad_name_provider.cpp b/qa/pcbnew/test_array_pad_name_provider.cpp index 04f4959b78..748b5613ac 100644 --- a/qa/pcbnew/test_array_pad_name_provider.cpp +++ b/qa/pcbnew/test_array_pad_name_provider.cpp @@ -82,8 +82,8 @@ std::vector<APNP_CASE> GetModuleAPNPCases() // simple linear numbering opts->m_2dArrayNumbering = false; - opts->m_numberingOffsetX = 1; - opts->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; + opts->m_pri_axis.SetOffset( 1 ); + opts->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC ); cases.push_back( { "Simple linear, skip some", @@ -98,8 +98,8 @@ std::vector<APNP_CASE> GetModuleAPNPCases() // simple linear numbering (again) opts->m_2dArrayNumbering = false; - opts->m_numberingOffsetX = 1; - opts->m_priAxisNumType = ARRAY_OPTIONS::NUMBERING_TYPE_T::NUMBERING_NUMERIC; + opts->m_pri_axis.SetOffset( 1 ); + opts->m_pri_axis.SetAxisType( ARRAY_AXIS::NUMBERING_TYPE::NUMBERING_NUMERIC ); cases.push_back( { "Simple linear, no module",