Eeschema: make field autoplace spacing flexible by field text height.
This commit is contained in:
parent
1bd860d1aa
commit
3c6c6dcc88
|
@ -63,9 +63,11 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#define FIELD_V_SPACING 100
|
#define FIELD_PADDING 10 // arbitrarily chosen for aesthetics
|
||||||
|
#define FIELD_PADDING_ALIGNED 18 // aligns 50 mil text to a 100 mil grid
|
||||||
|
#define WIRE_V_SPACING 100
|
||||||
#define HPADDING 25
|
#define HPADDING 25
|
||||||
#define VPADDING 50
|
#define VPADDING 25
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function round_n
|
* Function round_n
|
||||||
|
@ -127,7 +129,7 @@ public:
|
||||||
Kiface().KifaceSettings()->Read( AUTOPLACE_ALIGN_KEY, &m_align_to_grid, false );
|
Kiface().KifaceSettings()->Read( AUTOPLACE_ALIGN_KEY, &m_align_to_grid, false );
|
||||||
|
|
||||||
m_comp_bbox = m_component->GetBodyBoundingBox();
|
m_comp_bbox = m_component->GetBodyBoundingBox();
|
||||||
m_fbox_size = ComputeFBoxSize();
|
m_fbox_size = ComputeFBoxSize( /* aDynamic */ true );
|
||||||
|
|
||||||
m_power_symbol = ! m_component->IsInNetlist();
|
m_power_symbol = ! m_component->IsInNetlist();
|
||||||
|
|
||||||
|
@ -143,17 +145,16 @@ public:
|
||||||
*/
|
*/
|
||||||
void DoAutoplace( bool aManual )
|
void DoAutoplace( bool aManual )
|
||||||
{
|
{
|
||||||
|
bool force_wire_spacing = false;
|
||||||
SIDE field_side = choose_side_for_fields( aManual );
|
SIDE field_side = choose_side_for_fields( aManual );
|
||||||
wxPoint fbox_pos = field_box_placement( field_side );
|
wxPoint fbox_pos = field_box_placement( field_side );
|
||||||
EDA_RECT field_box( fbox_pos, m_fbox_size );
|
EDA_RECT field_box( fbox_pos, m_fbox_size );
|
||||||
|
|
||||||
if( aManual )
|
if( aManual )
|
||||||
{
|
force_wire_spacing = fit_fields_between_wires( &field_box, field_side );
|
||||||
fbox_pos = fit_fields_between_wires( field_box, field_side );
|
|
||||||
field_box.SetOrigin( fbox_pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the fields
|
// Move the fields
|
||||||
|
int last_y_coord = field_box.GetTop();
|
||||||
for( unsigned field_idx = 0; field_idx < m_fields.size(); ++field_idx )
|
for( unsigned field_idx = 0; field_idx < m_fields.size(); ++field_idx )
|
||||||
{
|
{
|
||||||
SCH_FIELD* field = m_fields[field_idx];
|
SCH_FIELD* field = m_fields[field_idx];
|
||||||
|
@ -163,7 +164,7 @@ public:
|
||||||
|
|
||||||
wxPoint pos(
|
wxPoint pos(
|
||||||
field_horiz_placement( field, field_box ),
|
field_horiz_placement( field, field_box ),
|
||||||
field_box.GetY() + (FIELD_V_SPACING * field_idx) );
|
field_vert_placement( field, field_box, &last_y_coord, !force_wire_spacing ) );
|
||||||
|
|
||||||
if( m_align_to_grid )
|
if( m_align_to_grid )
|
||||||
{
|
{
|
||||||
|
@ -179,29 +180,40 @@ public:
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Compute and return the size of the fields' bounding box.
|
* Compute and return the size of the fields' bounding box.
|
||||||
|
* @param aDynamic - if true, use dynamic spacing
|
||||||
*/
|
*/
|
||||||
wxSize ComputeFBoxSize()
|
wxSize ComputeFBoxSize( bool aDynamic )
|
||||||
{
|
{
|
||||||
int max_field_width = 0;
|
int max_field_width = 0;
|
||||||
|
int total_height = 0;
|
||||||
|
|
||||||
BOOST_FOREACH( SCH_FIELD* field, m_fields )
|
BOOST_FOREACH( SCH_FIELD* field, m_fields )
|
||||||
{
|
{
|
||||||
int field_width;
|
int field_width;
|
||||||
|
int field_height;
|
||||||
|
|
||||||
if( m_component->GetTransform().y1 )
|
if( m_component->GetTransform().y1 )
|
||||||
{
|
{
|
||||||
field->SetOrientation( TEXT_ORIENT_VERT );
|
field->SetOrientation( TEXT_ORIENT_VERT );
|
||||||
field_width = field->GetBoundingBox().GetHeight();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field->SetOrientation( TEXT_ORIENT_HORIZ );
|
field->SetOrientation( TEXT_ORIENT_HORIZ );
|
||||||
field_width = field->GetBoundingBox().GetWidth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field_width = field->GetBoundingBox().GetWidth();
|
||||||
|
field_height = field->GetBoundingBox().GetHeight();
|
||||||
|
|
||||||
max_field_width = std::max( max_field_width, field_width );
|
max_field_width = std::max( max_field_width, field_width );
|
||||||
|
|
||||||
|
if( aDynamic )
|
||||||
|
total_height += field_height + get_field_padding();
|
||||||
|
else
|
||||||
|
total_height += WIRE_V_SPACING;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxSize( max_field_width, int( FIELD_V_SPACING * (m_fields.size() - 1) ) );
|
return wxSize( max_field_width, total_height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -519,16 +531,16 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Function fit_fields_between_wires
|
* Function fit_fields_between_wires
|
||||||
* Shift a field box up or down a bit to make the fields fit between some wires.
|
* Shift a field box up or down a bit to make the fields fit between some wires.
|
||||||
* Returns the new position of the field bounding box.
|
* Returns true if a shift was made.
|
||||||
*/
|
*/
|
||||||
wxPoint fit_fields_between_wires( const EDA_RECT& aBox, SIDE aSide )
|
bool fit_fields_between_wires( EDA_RECT* aBox, SIDE aSide )
|
||||||
{
|
{
|
||||||
if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM )
|
if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM )
|
||||||
return aBox.GetPosition();
|
return false;
|
||||||
|
|
||||||
std::vector<SCH_ITEM*> colliders = filtered_colliders( aBox );
|
std::vector<SCH_ITEM*> colliders = filtered_colliders( *aBox );
|
||||||
if( colliders.empty() )
|
if( colliders.empty() )
|
||||||
return aBox.GetPosition();
|
return false;
|
||||||
|
|
||||||
// Find the offset of the wires for proper positioning
|
// Find the offset of the wires for proper positioning
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -537,24 +549,28 @@ protected:
|
||||||
{
|
{
|
||||||
SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
|
SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
|
||||||
if( !line )
|
if( !line )
|
||||||
return aBox.GetPosition();
|
return false;
|
||||||
wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
|
wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
|
||||||
if( start.y != end.y )
|
if( start.y != end.y )
|
||||||
return aBox.GetPosition();
|
return false;
|
||||||
|
|
||||||
int this_offset = (3 * FIELD_V_SPACING / 2) - ( start.y % FIELD_V_SPACING );
|
int this_offset = (3 * WIRE_V_SPACING / 2) - ( start.y % WIRE_V_SPACING );
|
||||||
if( offset == 0 )
|
if( offset == 0 )
|
||||||
offset = this_offset;
|
offset = this_offset;
|
||||||
else if( offset != this_offset )
|
else if( offset != this_offset )
|
||||||
return aBox.GetPosition();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aSide == SIDE_TOP )
|
if( aSide == SIDE_TOP )
|
||||||
offset = -offset;
|
offset = -offset;
|
||||||
|
|
||||||
wxPoint pos = aBox.GetPosition();
|
wxPoint pos = aBox->GetPosition();
|
||||||
pos.y = round_n( pos.y - offset, FIELD_V_SPACING, aSide == SIDE_BOTTOM ) + offset;
|
pos.y = round_n( pos.y - offset, WIRE_V_SPACING, aSide == SIDE_BOTTOM ) + offset;
|
||||||
return pos;
|
|
||||||
|
// Compensate for padding
|
||||||
|
pos.y += WIRE_V_SPACING / 2;
|
||||||
|
aBox->SetOrigin( pos );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -597,6 +613,59 @@ protected:
|
||||||
return field_xcoord;
|
return field_xcoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function field_vert_placement
|
||||||
|
* Place a field vertically. Because field vertical placements accumulate,
|
||||||
|
* this takes a pointer to a vertical position accumulator.
|
||||||
|
*
|
||||||
|
* @param aField - the field to place.
|
||||||
|
* @param aFieldBox - box in which fields will be placed.
|
||||||
|
* @param aPosAccum - pointer to a position accumulator
|
||||||
|
* @param aDynamic - use dynamic spacing
|
||||||
|
*
|
||||||
|
* @return Correct field vertical position
|
||||||
|
*/
|
||||||
|
int field_vert_placement( SCH_FIELD *aField, const EDA_RECT &aFieldBox, int *aPosAccum,
|
||||||
|
bool aDynamic )
|
||||||
|
{
|
||||||
|
int field_height;
|
||||||
|
int padding;
|
||||||
|
|
||||||
|
if( aDynamic )
|
||||||
|
{
|
||||||
|
if( m_component->GetTransform().y1 )
|
||||||
|
field_height = aField->GetBoundingBox().GetWidth();
|
||||||
|
else
|
||||||
|
field_height = aField->GetBoundingBox().GetHeight();
|
||||||
|
field_height = aField->GetBoundingBox().GetHeight();
|
||||||
|
|
||||||
|
padding = get_field_padding();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field_height = WIRE_V_SPACING / 2;
|
||||||
|
padding = WIRE_V_SPACING / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int placement = *aPosAccum + padding / 2 + field_height / 2;
|
||||||
|
|
||||||
|
*aPosAccum += padding + field_height;
|
||||||
|
|
||||||
|
return placement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function get_field_padding
|
||||||
|
* Return the desired padding between fields.
|
||||||
|
*/
|
||||||
|
int get_field_padding()
|
||||||
|
{
|
||||||
|
if( m_align_to_grid )
|
||||||
|
return FIELD_PADDING_ALIGNED;
|
||||||
|
else
|
||||||
|
return FIELD_PADDING;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const AUTOPLACER::SIDE AUTOPLACER::SIDE_TOP( 0, -1 );
|
const AUTOPLACER::SIDE AUTOPLACER::SIDE_TOP( 0, -1 );
|
||||||
|
|
Loading…
Reference in New Issue