53 #include <boost/range/adaptor/reversed.hpp> 69 #define FIELD_PADDING Mils2iu( 10 ) // arbitrarily chosen for aesthetics 70 #define WIRE_V_SPACING Mils2iu( 100 ) 71 #define HPADDING Mils2iu( 25 ) 72 #define VPADDING Mils2iu( 25 ) 77 template<
typename T> T
round_n(
const T& value,
const T& n,
bool aRoundUp )
80 return n * (value / n + (aRoundUp ? 1 : 0));
91 return static_cast<EDA_TEXT_HJUSTIFY_T>( x );
120 auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>(
Kiface().KifaceSettings() );
148 bool force_wire_spacing =
false;
157 int last_y_coord = field_box.
GetTop();
159 for(
unsigned field_idx = 0; field_idx <
m_fields.size(); ++field_idx )
171 pos.x =
round_n( pos.x, Mils2iu( 50 ), field_side.x >= 0 );
172 pos.y =
round_n( pos.y, Mils2iu( 50 ), field_side.y >= 0 );
186 int max_field_width = 0;
187 int total_height = 0;
199 field_width = field->GetBoundingBox().GetWidth();
200 field_height = field->GetBoundingBox().GetHeight();
202 max_field_width = std::max( max_field_width, field_width );
207 total_height +=
round_n( field_height, Mils2iu( 50 ),
true );
212 return wxSize( max_field_width, total_height );
229 wxFAIL_MSG(
"Invalid pin orientation" );
239 unsigned pin_count = 0;
260 wxCHECK_RET(
m_screen,
"getPossibleCollisions() with null m_screen" );
264 if(
SCH_COMPONENT* candidate = dynamic_cast<SCH_COMPONENT*>( item ) )
269 std::vector<SCH_FIELD*> fields;
270 candidate->GetFields( fields,
true );
273 aItems.push_back( field );
276 aItems.push_back( item );
286 std::vector<SCH_ITEM*> filtered;
292 if(
SCH_COMPONENT* item_comp = dynamic_cast<SCH_COMPONENT*>( item ) )
293 item_box = item_comp->GetBodyBoundingBox();
295 item_box = item->GetBoundingBox();
298 filtered.push_back( item );
315 std::vector<SIDE_AND_NPINS> sides( sides_init, sides_init +
arrayDim( sides_init ) );
318 int orient_angle = orient & 0xff;
330 switch( orient_angle )
333 std::swap( sides[0], sides[1] );
334 std::swap( sides[1], sides[3] );
338 std::swap( sides[0], sides[2] );
339 std::swap( sides[1], sides[2] );
343 std::swap( sides[0], sides[3] );
347 std::swap( sides[1], sides[2] );
357 std::swap( sides[0], sides[2] );
363 std::swap( sides[0], sides[1] );
364 std::swap( sides[1], sides[3] );
377 std::vector<SIDE> sides( sides_init, sides_init +
arrayDim( sides_init ) );
378 std::vector<SIDE_AND_COLL> colliding;
381 for(
SIDE side : sides )
389 SCH_LINE* line = dynamic_cast<SCH_LINE*>( collider );
391 if( line && !side.x )
407 colliding.push_back( { side, collision } );
418 const std::vector<SIDE_AND_COLL>& aCollidingSides,
424 std::vector<SIDE_AND_NPINS>::iterator it = aSides.begin();
426 while( it != aSides.end() )
432 if( collision.side == it->side && collision.collision == aCollision )
442 if( it->pins <= sel.
pins )
448 it = aSides.erase( it );
464 std::reverse( sides.begin(), sides.end() );
467 if( aAvoidCollisions )
474 for(
SIDE_AND_NPINS& each_side : sides | boost::adaptors::reversed )
476 if( !each_side.pins )
return each_side.side;
481 if( each_side.pins <= side.pins )
483 side.pins = each_side.pins;
484 side.side = each_side.side;
514 if( aFieldSide.x != 0 )
516 else if( aFieldSide.y != 0 )
519 fbox_center.x += aFieldSide.x * offs_x;
520 fbox_center.y += aFieldSide.y * offs_y;
522 wxPoint fbox_pos( fbox_center.x -
m_fbox_size.GetWidth() / 2,
539 if( colliders.empty() )
547 SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
554 if( start.y != end.y )
560 offset = this_offset;
561 else if( offset != this_offset )
595 switch( field_hjust )
598 field_xcoord = aFieldBox.
GetLeft();
601 field_xcoord = aFieldBox.
Centre().x;
604 field_xcoord = aFieldBox.
GetRight();
607 wxFAIL_MSG(
"Unexpected value for SCH_FIELD::GetHorizJustify()" );
608 field_xcoord = aFieldBox.
Centre().x;
639 padding =
round_n( field_height, Mils2iu( 50 ),
true ) - field_height;
647 int placement = *aPosAccum + padding / 2 + field_height / 2;
649 *aPosAccum += padding + field_height;
676 wxASSERT_MSG( aScreen,
"A SCH_SCREEN pointer must be given for manual autoplacement" );
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
LIB_PIN * GetLibPin() const
std::vector< SCH_FIELD * > m_fields
std::vector< SIDE_AND_NPINS > getPreferredSides()
Return a list with the preferred field sides for the component, in decreasing order of preference.
int GetOrientation()
Get the display symbol orientation.
wxPoint GetStartPoint() const
bool collide(T aObject, U aAnotherObject, int aMinDistance)
collide template method
bool fitFieldsBetweenWires(EDA_RECT *aBox, SIDE aSide)
Shift a field box up or down a bit to make the fields fit between some wires.
EE_TYPE Overlapping(const EDA_RECT &aRect)
void SetOrigin(const wxPoint &pos)
int PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
wxPoint fieldBoxPlacement(SIDE aFieldSide)
Return the position of the field bounding box.
SIDE getPinSide(SCH_PIN *aPin)
Return the side that a pin is on.
FIELDS_AUTOPLACED m_fieldsAutoplaced
int fieldHorizPlacement(SCH_FIELD *aField, const EDA_RECT &aFieldBox)
Place a field horizontally, taking into account the field width and justification.
std::vector< SCH_ITEM * > filterCollisions(const EDA_RECT &aRect)
Filter a list of possible colliders to include only those that actually collide with a given rectangl...
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
static const SIDE SIDE_LEFT
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
std::vector< SCH_ITEM * > m_colliders
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the fields.
EDA_TEXT_HJUSTIFY_T TO_HJUSTIFY(int x)
Convert an integer to a horizontal justification; neg=L zero=C pos=R.
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
const wxPoint GetPosition() const
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
wxSize computeFBoxSize(bool aDynamic)
Compute and return the size of the fields' bounding box.
AUTOPLACER(SCH_COMPONENT *aSymbol, SCH_SCREEN *aScreen)
int fieldVertPlacement(SCH_FIELD *aField, const EDA_RECT &aFieldBox, int *aPosAccum, bool aDynamic)
Place a field vertically.
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
unsigned pinsOnSide(SIDE aSide)
Count the number of pins on a side of the component.
TRANSFORM & GetTransform()
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieves a list of the SCH_PINs for the given sheet path.
static const SIDE SIDE_RIGHT
T round_n(const T &value, const T &n, bool aRoundUp)
Round up/down to the nearest multiple of n.
SIDE chooseSideForFields(bool aAvoidCollisions)
Look where a component's pins are to pick a side to put the fields on.
Segment description base class to describe items which have 2 end points (track, wire,...
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
static const SIDE SIDE_BOTTOM
Handle the component boundary box.
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Automatically orient all the fields in the component.
std::vector< SIDE_AND_COLL > getCollidingSides()
Return a list of the sides where a field set would collide with another item.
bool IsHorizJustifyFlipped() const
Function IsHorizJustifyFlipped Returns whether the field will be rendered with the horizontal justifi...
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
void DoAutoplace(bool aManual)
Do the actual autoplacement.
static const SIDE SIDE_TOP
void SetPosition(const wxPoint &aPosition) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
SIDE_AND_NPINS chooseSideFiltered(std::vector< SIDE_AND_NPINS > &aSides, const std::vector< SIDE_AND_COLL > &aCollidingSides, COLLISION aCollision, SIDE_AND_NPINS aLastSelection)
Choose a side for the fields, filtered on only one side collision type.
void justifyField(SCH_FIELD *aField, SIDE aFieldSide)
Set the justification of a field based on the side it's supposed to be on, taking into account whethe...
void getPossibleCollisions(std::vector< SCH_ITEM * > &aItems)
Populate a list of all drawing items that may collide with the fields.
wxPoint GetEndPoint() const