7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-11 09:00:13 +00:00

Pcbnew: Add inward/outward dimension arrows

This adds a toggle between outward ( |<--->| ) and inward
( -->|----|<-- ) dimensions.

The original merge request for this feature had more nice
features to it: automatic switching and an 'outward' version of the
radial dimension. However, both of these are very tricky problems, and
need more thought: for example, if the radial dimension is overloaded
into a diameter dimension based on the arrow direction, then you have
implement the fiddly concept of a prefix override, and it also make
the point editor much harder to make seamless.

So, rather then delay the very good and useful upgrade of
the "normal" ortho/aligned dimensions, just sidestep the
issue by not doing the radial lines or auto detection right now.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/5819
This commit is contained in:
Hasan Jaafar 2023-07-07 03:43:28 +03:00 committed by John Beard
parent ab6049ec0b
commit 6e9188713b
10 changed files with 5358 additions and 5029 deletions

View File

@ -41,6 +41,7 @@ arrow1a
arrow1b
arrow2a
arrow2b
arrow_direction
arrow_length
at
attr
@ -180,6 +181,7 @@ host
href
id
image
inward
island
island_removal_mode
island_area_min
@ -237,6 +239,7 @@ orientation
orthogonal
other_layers_line_width
other_layers_text_dims
outward
oval
override_value
pad

View File

@ -211,6 +211,12 @@ bool DIALOG_DIMENSION_PROPERTIES::TransferDataToWindow()
case DIM_UNITS_MODE::AUTOMATIC: m_cbUnits->SetSelection( 3 ); break;
}
switch ( m_dimension->GetArrowDirection() )
{
case DIM_ARROW_DIRECTION::INWARD: m_cbArrowDirection->SetSelection( 0 ); break;
case DIM_ARROW_DIRECTION::OUTWARD: m_cbArrowDirection->SetSelection( 1 ); break;
}
m_cbUnitsFormat->SetSelection( static_cast<int>( m_dimension->GetUnitsFormat() ) );
m_cbPrecision->SetSelection( static_cast<int>( m_dimension->GetPrecision() ) );
@ -383,6 +389,11 @@ void DIALOG_DIMENSION_PROPERTIES::updateDimensionFromDialog( PCB_DIMENSION_BASE*
aTarget->SetSuffix( board->ConvertCrossReferencesToKIIDs( m_txtSuffix->GetValue() ) );
aTarget->SetLayer( static_cast<PCB_LAYER_ID>( m_cbLayerActual->GetLayerSelection() ) );
switch ( m_cbArrowDirection->GetSelection() ) {
case 0: aTarget->SetArrowDirection( DIM_ARROW_DIRECTION::INWARD ); break;
case 1: aTarget->SetArrowDirection( DIM_ARROW_DIRECTION::OUTWARD ); break;
}
switch( m_cbUnits->GetSelection() )
{
case 0: aTarget->SetUnitsMode( DIM_UNITS_MODE::INCHES ); break;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -169,6 +169,10 @@ DIALOG_DIMENSION_PROPERTIES_BASE::DIALOG_DIMENSION_PROPERTIES_BASE( wxWindow* pa
gbSizerFormat->Add( m_lblPrecision, wxGBPosition( 2, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_lblArrowDirection = new wxStaticText( m_sizerFormat->GetStaticBox(), wxID_ANY, _("Arrow Direction:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblArrowDirection->Wrap( -1 );
gbSizerFormat->Add( m_lblArrowDirection, wxGBPosition( 3, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
wxString m_cbPrecisionChoices[] = { _("0"), _("0.0"), _("0.00"), _("0.000"), _("0.0000"), _("0.00000"), _("0.00 in / 0 mils / 0.0 mm"), _("0.000 / 0 / 0.00"), _("0.0000 / 0.0 / 0.000"), _("0.00000 / 0.00 / 0.0000") };
int m_cbPrecisionNChoices = sizeof( m_cbPrecisionChoices ) / sizeof( wxString );
m_cbPrecision = new wxChoice( m_sizerFormat->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbPrecisionNChoices, m_cbPrecisionChoices, 0 );
@ -177,17 +181,25 @@ DIALOG_DIMENSION_PROPERTIES_BASE::DIALOG_DIMENSION_PROPERTIES_BASE( wxWindow* pa
gbSizerFormat->Add( m_cbPrecision, wxGBPosition( 2, 5 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_cbSuppressZeroes = new wxCheckBox( m_sizerFormat->GetStaticBox(), wxID_ANY, _("Suppress trailing zeroes"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbSuppressZeroes->SetToolTip( _("When checked, \"0.100\" will be shown as \"0.1\" even if the precision setting is higher") );
wxString m_cbArrowDirectionChoices[] = { _("Inward"), _("Outward") };
int m_cbArrowDirectionNChoices = sizeof( m_cbArrowDirectionChoices ) / sizeof( wxString );
m_cbArrowDirection = new wxChoice( m_sizerFormat->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbArrowDirectionNChoices, m_cbArrowDirectionChoices, 0 );
m_cbArrowDirection->SetSelection( 0 );
m_cbArrowDirection->SetToolTip( _("Chose Dimension Arrow Direction\nAutomatic: Determined based on text position.\nInward: >-----<\nOutward: <----->") );
gbSizerFormat->Add( m_cbSuppressZeroes, wxGBPosition( 3, 4 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL, 5 );
gbSizerFormat->Add( m_cbArrowDirection, wxGBPosition( 3, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_cbLayer = new PCB_LAYER_BOX_SELECTOR( m_sizerFormat->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
gbSizerFormat->Add( m_cbLayer, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_lblLayer = new wxStaticText( m_sizerFormat->GetStaticBox(), wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblLayer->Wrap( -1 );
gbSizerFormat->Add( m_lblLayer, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_cbLayer = new PCB_LAYER_BOX_SELECTOR( m_sizerFormat->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
gbSizerFormat->Add( m_cbLayer, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_cbSuppressZeroes = new wxCheckBox( m_sizerFormat->GetStaticBox(), wxID_ANY, _("Suppress trailing zeroes"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbSuppressZeroes->SetToolTip( _("When checked, \"0.100\" will be shown as \"0.1\" even if the precision setting is higher") );
gbSizerFormat->Add( m_cbSuppressZeroes, wxGBPosition( 4, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_lblPreview = new wxStaticText( m_sizerFormat->GetStaticBox(), wxID_ANY, _("Preview:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblPreview->Wrap( -1 );
@ -195,7 +207,7 @@ DIALOG_DIMENSION_PROPERTIES_BASE::DIALOG_DIMENSION_PROPERTIES_BASE( wxWindow* pa
m_staticTextPreview = new wxStaticText( m_sizerFormat->GetStaticBox(), wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextPreview->Wrap( -1 );
gbSizerFormat->Add( m_staticTextPreview, wxGBPosition( 4, 1 ), wxGBSpan( 1, 5 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxEXPAND, 5 );
gbSizerFormat->Add( m_staticTextPreview, wxGBPosition( 4, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxTOP|wxEXPAND, 5 );
gbSizerFormat->AddGrowableCol( 1 );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -38,7 +38,6 @@ class PCB_LAYER_BOX_SELECTOR;
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_DIMENSION_PROPERTIES_BASE
///////////////////////////////////////////////////////////////////////////////
@ -71,10 +70,12 @@ class DIALOG_DIMENSION_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_lblSuffix;
wxTextCtrl* m_txtSuffix;
wxStaticText* m_lblPrecision;
wxStaticText* m_lblArrowDirection;
wxChoice* m_cbPrecision;
wxCheckBox* m_cbSuppressZeroes;
wxStaticText* m_lblLayer;
wxChoice* m_cbArrowDirection;
PCB_LAYER_BOX_SELECTOR* m_cbLayer;
wxStaticText* m_lblLayer;
wxCheckBox* m_cbSuppressZeroes;
wxStaticText* m_lblPreview;
wxStaticText* m_staticTextPreview;
wxStaticBoxSizer* m_sizerText;

View File

@ -40,6 +40,7 @@
#include <settings/settings_manager.h>
#include <trigo.h>
static const int INWARD_ARROW_LENGTH_TO_HEAD_RATIO = 2;
static const EDA_ANGLE s_arrowAngle( 27.5, DEGREES_T );
@ -133,6 +134,7 @@ PCB_DIMENSION_BASE::PCB_DIMENSION_BASE( BOARD_ITEM* aParent, KICAD_T aType ) :
m_units( EDA_UNITS::INCHES ),
m_autoUnits( false ),
m_unitsFormat( DIM_UNITS_FORMAT::BARE_SUFFIX ),
m_arrowDirection( DIM_ARROW_DIRECTION::OUTWARD ),
m_precision( DIM_PRECISION::X_XXXX ),
m_suppressZeroes( false ),
m_lineThickness( pcbIUScale.mmToIU( 0.2 ) ),
@ -248,6 +250,26 @@ double PCB_DIMENSION_BASE::Similarity( const BOARD_ITEM& aOther ) const
}
void PCB_DIMENSION_BASE::drawAnArrow( VECTOR2I startPoint, EDA_ANGLE anAngle, int aLength )
{
if( aLength )
{
VECTOR2I tailEnd( aLength, 0 );
RotatePoint( tailEnd, -anAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( startPoint, startPoint + tailEnd ) );
}
VECTOR2I arrowEndPos( m_arrowLength, 0 );
VECTOR2I arrowEndNeg( m_arrowLength, 0 );
RotatePoint( arrowEndPos, -anAngle + s_arrowAngle );
RotatePoint( arrowEndNeg, -anAngle - s_arrowAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( startPoint, startPoint + arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( startPoint, startPoint + arrowEndNeg ) );
}
void PCB_DIMENSION_BASE::updateText()
{
wxString text = m_overrideTextEnabled ? m_valueString : GetValueText();
@ -796,18 +818,21 @@ void PCB_DIM_ALIGNED::updateGeometry()
CollectKnockedOutSegments( polyBox, crossbar, m_shapes );
// Add arrows
VECTOR2I arrowEndPos( m_arrowLength, 0 );
VECTOR2I arrowEndNeg( m_arrowLength, 0 );
RotatePoint( arrowEndPos, -EDA_ANGLE( dimension ) + s_arrowAngle );
RotatePoint( arrowEndNeg, -EDA_ANGLE( dimension ) - s_arrowAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart, m_crossBarStart + arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart, m_crossBarStart + arrowEndNeg ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd, m_crossBarEnd - arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd, m_crossBarEnd - arrowEndNeg ) );
if( m_arrowDirection == DIM_ARROW_DIRECTION::INWARD )
{
drawAnArrow( m_crossBarStart, EDA_ANGLE( dimension ) + EDA_ANGLE( 180 ),
m_arrowLength * INWARD_ARROW_LENGTH_TO_HEAD_RATIO );
drawAnArrow( m_crossBarEnd, EDA_ANGLE( dimension ),
m_arrowLength * INWARD_ARROW_LENGTH_TO_HEAD_RATIO );
}
else
{
drawAnArrow( m_crossBarStart, EDA_ANGLE( dimension ), 0 );
drawAnArrow( m_crossBarEnd, EDA_ANGLE( dimension ) + EDA_ANGLE( 180 ), 0 );
}
}
void PCB_DIM_ALIGNED::updateText()
{
VECTOR2I crossbarCenter( ( m_crossBarEnd - m_crossBarStart ) / 2 );
@ -976,17 +1001,20 @@ void PCB_DIM_ORTHOGONAL::updateGeometry()
CollectKnockedOutSegments( polyBox, crossbar, m_shapes );
// Add arrows
EDA_ANGLE crossBarAngle( m_crossBarEnd - m_crossBarStart );
VECTOR2I arrowEndPos( m_arrowLength, 0 );
VECTOR2I arrowEndNeg( m_arrowLength, 0 );
RotatePoint( arrowEndPos, -crossBarAngle + s_arrowAngle );
RotatePoint( arrowEndNeg, -crossBarAngle - s_arrowAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart, m_crossBarStart + arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart, m_crossBarStart + arrowEndNeg ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd, m_crossBarEnd - arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd, m_crossBarEnd - arrowEndNeg ) );
if( m_arrowDirection == DIM_ARROW_DIRECTION::INWARD )
{
// Arrows with fixed length.
drawAnArrow( m_crossBarStart, crossBarAngle + EDA_ANGLE( 180 ),
m_arrowLength * INWARD_ARROW_LENGTH_TO_HEAD_RATIO );
drawAnArrow( m_crossBarEnd, crossBarAngle, m_arrowLength * INWARD_ARROW_LENGTH_TO_HEAD_RATIO );
}
else
{
drawAnArrow( m_crossBarStart, crossBarAngle, 0 );
drawAnArrow( m_crossBarEnd, crossBarAngle + EDA_ANGLE( 180 ), 0 );
}
}
@ -1166,15 +1194,7 @@ void PCB_DIM_LEADER::updateGeometry()
m_shapes.emplace_back( new SHAPE_SEGMENT( start, *arrowSegEnd ) );
// Add arrows
VECTOR2I arrowEndPos( m_arrowLength, 0 );
VECTOR2I arrowEndNeg( m_arrowLength, 0 );
RotatePoint( arrowEndPos, -EDA_ANGLE( firstLine ) + s_arrowAngle );
RotatePoint( arrowEndNeg, -EDA_ANGLE( firstLine ) - s_arrowAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( start, start + arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( start, start + arrowEndNeg ) );
drawAnArrow( start, EDA_ANGLE( firstLine ), 0 );
if( !GetText().IsEmpty() )
{
@ -1335,14 +1355,7 @@ void PCB_DIM_RADIAL::updateGeometry()
CollectKnockedOutSegments( polyBox, arrowSeg, m_shapes );
CollectKnockedOutSegments( polyBox, textSeg, m_shapes );
// Add arrows
VECTOR2I arrowEndPos( m_arrowLength, 0 );
VECTOR2I arrowEndNeg( m_arrowLength, 0 );
RotatePoint( arrowEndPos, -EDA_ANGLE( radial ) + s_arrowAngle );
RotatePoint( arrowEndNeg, -EDA_ANGLE( radial ) - s_arrowAngle );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_end, m_end + arrowEndPos ) );
m_shapes.emplace_back( new SHAPE_SEGMENT( m_end, m_end + arrowEndNeg ) );
drawAnArrow( m_end, EDA_ANGLE( radial ), 0 );
}
@ -1440,6 +1453,10 @@ static struct DIMENSION_DESC
.Map( DIM_UNITS_MODE::MILLIMETRES, _HKI( "Millimeters" ) )
.Map( DIM_UNITS_MODE::AUTOMATIC, _HKI( "Automatic" ) );
ENUM_MAP<DIM_ARROW_DIRECTION>::Instance()
.Map( DIM_ARROW_DIRECTION::INWARD, _HKI( "Inward" ) )
.Map( DIM_ARROW_DIRECTION::OUTWARD, _HKI( "Outward" ) );
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( PCB_DIMENSION_BASE );
propMgr.AddTypeCast( new TYPE_CAST<PCB_DIMENSION_BASE, PCB_TEXT> );
@ -1462,7 +1479,13 @@ static struct DIMENSION_DESC
auto isNotLeader =
[]( INSPECTABLE* aItem ) -> bool
{
return dynamic_cast<PCB_DIM_LEADER*>( aItem ) == nullptr;
return dynamic_cast<PCB_DIM_LEADER*>( aItem ) == nullptr;
};
auto isMultiArrowDirection =
[]( INSPECTABLE* aItem ) -> bool
{
return dynamic_cast<PCB_DIM_ALIGNED*>( aItem ) != nullptr;
};
propMgr.AddProperty( new PROPERTY<PCB_DIMENSION_BASE, wxString>( _HKI( "Prefix" ),
@ -1500,6 +1523,11 @@ static struct DIMENSION_DESC
groupDimension )
.SetAvailableFunc( isNotLeader );
propMgr.AddProperty( new PROPERTY_ENUM<PCB_DIMENSION_BASE, DIM_ARROW_DIRECTION>( _HKI( "Arrow Direction"),
&PCB_DIMENSION_BASE::ChangeArrowDirection, &PCB_DIMENSION_BASE::GetArrowDirection ),
groupDimension )
.SetAvailableFunc( isMultiArrowDirection );
const wxString groupText = _HKI( "Text Properties" );
const auto isTextOrientationWriteable =
@ -1525,6 +1553,7 @@ static struct DIMENSION_DESC
ENUM_TO_WXANY( DIM_PRECISION )
ENUM_TO_WXANY( DIM_UNITS_FORMAT )
ENUM_TO_WXANY( DIM_UNITS_MODE )
ENUM_TO_WXANY( DIM_ARROW_DIRECTION )
static struct ALIGNED_DIMENSION_DESC

View File

@ -76,6 +76,15 @@ enum class DIM_UNITS_MODE
AUTOMATIC
};
/**
* Used for dimension's arrow.
*/
enum class DIM_ARROW_DIRECTION
{
INWARD, ///< >-----<
OUTWARD, ///< <----->
};
/**
* Frame to show around dimension text
*/
@ -185,6 +194,19 @@ public:
Update();
}
DIM_ARROW_DIRECTION GetArrowDirection() const { return m_arrowDirection; }
void SetArrowDirection( const DIM_ARROW_DIRECTION& aDirection )
{
m_arrowDirection = aDirection;
}
void ChangeArrowDirection( const DIM_ARROW_DIRECTION& aDirection )
{
SetArrowDirection( aDirection );
updateText();
updateGeometry();
}
EDA_UNITS GetUnits() const { return m_units; }
void SetUnits( EDA_UNITS aUnits );
@ -313,28 +335,39 @@ protected:
template<typename ShapeType>
void addShape( const ShapeType& aShape );
/**
* Draws an arrow and updates the shape container.
* example arrow 0Deg tail:4 (---->)
*
* @param startPoint arrow point.
* @param anAngle arrow angle.
* @param aLength arrow tail length.
*/
void drawAnArrow( VECTOR2I aStartPoint, EDA_ANGLE anAngle, int aLength );
// Value format
bool m_overrideTextEnabled; ///< Manually specify the displayed measurement value
wxString m_valueString; ///< Displayed value when m_overrideValue = true
wxString m_prefix; ///< String prepended to the value
wxString m_suffix; ///< String appended to the value
EDA_UNITS m_units; ///< 0 = inches, 1 = mm
bool m_autoUnits; ///< If true, follow the currently selected UI units
DIM_UNITS_FORMAT m_unitsFormat; ///< How to render the units suffix
DIM_PRECISION m_precision; ///< Number of digits to display after decimal
bool m_suppressZeroes; ///< Suppress trailing zeroes
bool m_overrideTextEnabled; ///< Manually specify the displayed measurement value
wxString m_valueString; ///< Displayed value when m_overrideValue = true
wxString m_prefix; ///< String prepended to the value
wxString m_suffix; ///< String appended to the value
EDA_UNITS m_units; ///< 0 = inches, 1 = mm
bool m_autoUnits; ///< If true, follow the currently selected UI units
DIM_UNITS_FORMAT m_unitsFormat; ///< How to render the units suffix
DIM_ARROW_DIRECTION m_arrowDirection; ///< direction of dimension arrow.
DIM_PRECISION m_precision; ///< Number of digits to display after decimal
bool m_suppressZeroes; ///< Suppress trailing zeroes
// Geometry
int m_lineThickness; ///< Thickness used for all graphics in the dimension
int m_arrowLength; ///< Length of arrow shapes
int m_extensionOffset; ///< Distance from feature points to extension line start
DIM_TEXT_POSITION m_textPosition; ///< How to position the text
bool m_keepTextAligned; ///< Calculate text orientation to match dimension
int m_lineThickness; ///< Thickness used for all graphics in the dimension
int m_arrowLength; ///< Length of arrow shapes
int m_extensionOffset; ///< Distance from feature points to extension line start
DIM_TEXT_POSITION m_textPosition; ///< How to position the text
bool m_keepTextAligned; ///< Calculate text orientation to match dimension
// Internal
int m_measuredValue; ///< value of PCB dimensions
VECTOR2I m_start;
VECTOR2I m_end;
int m_measuredValue; ///< value of PCB dimensions
VECTOR2I m_start;
VECTOR2I m_end;
///< Internal cache of drawn shapes
std::vector<std::shared_ptr<SHAPE>> m_shapes;

View File

@ -955,6 +955,20 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_DIMENSION_BASE* aDimension, int aNest
formatInternalUnits( aDimension->GetArrowLength() ).c_str(),
static_cast<int>( aDimension->GetTextPositionMode() ) );
if( ortho || aligned )
{
switch( aDimension->GetArrowDirection() )
{
case DIM_ARROW_DIRECTION::OUTWARD:
m_out->Print( 0, " (arrow_direction outward)" );
break;
case DIM_ARROW_DIRECTION::INWARD:
m_out->Print( 0, " (arrow_direction inward)" );
break;
// No default, handle all cases
}
}
if( aligned )
{
m_out->Print( 0, " (extension_height %s)",

View File

@ -168,7 +168,8 @@ class PCB_IO_KICAD_SEXPR; // forward decl
//#define SEXPR_BOARD_FILE_VERSION 20241006 // Via stacks
//#define SEXPR_BOARD_FILE_VERSION 20241007 // Tracks can have soldermask layer and margin
//#define SEXPR_BOARD_FILE_VERSION 20241009 // Evolve placement rule areas file format
#define SEXPR_BOARD_FILE_VERSION 20241010 // Graphic shapes can have soldermask layer and margin
//#define SEXPR_BOARD_FILE_VERSION 20241010 // Graphic shapes can have soldermask layer and margin
#define SEXPR_BOARD_FILE_VERSION 20241030 // Dimension arrow directions
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting

View File

@ -3913,6 +3913,10 @@ PCB_DIMENSION_BASE* PCB_IO_KICAD_SEXPR_PARSER::parseDIMENSION( BOARD_ITEM* aPare
}
NeedRIGHT();
// Before parsing further, set default properites for old KiCad file
// versions that didnt have these properties:
dim->SetArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
@ -4111,7 +4115,22 @@ PCB_DIMENSION_BASE* PCB_IO_KICAD_SEXPR_PARSER::parseDIMENSION( BOARD_ITEM* aPare
NeedRIGHT();
break;
case T_arrow_direction:
{
token = NextTok();
if( token == T_inward )
dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::INWARD );
else if( token == T_outward )
dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
else
Expecting( "inward or outward" );
NeedRIGHT();
break;
}
case T_arrow_length:
dim->SetArrowLength( parseBoardUnits( "arrow length value" ) );
NeedRIGHT();
break;
@ -4158,8 +4177,8 @@ PCB_DIMENSION_BASE* PCB_IO_KICAD_SEXPR_PARSER::parseDIMENSION( BOARD_ITEM* aPare
}
default:
Expecting( "thickness, arrow_length, text_position_mode, extension_height, "
"extension_offset" );
Expecting( "thickness, arrow_length, arrow_direction, text_position_mode, "
"extension_height, extension_offset" );
}
}