53 #include <boost/range/adaptor/reversed.hpp> 67 #define FIELD_PADDING 10 // arbitrarily chosen for aesthetics 68 #define FIELD_PADDING_ALIGNED 18 // aligns 50 mil text to a 100 mil grid 69 #define WIRE_V_SPACING 100 77 template<
typename T> T
round_n(
const T& value,
const T& n,
bool aRoundUp )
80 return n * (value / n + (aRoundUp ? 1 : 0));
126 :m_screen( aScreen ), m_component( aComponent )
128 m_component->
GetFields( m_fields,
true );
149 bool force_wire_spacing =
false;
152 EDA_RECT field_box( fbox_pos, m_fbox_size );
158 int last_y_coord = field_box.
GetTop();
159 for(
unsigned field_idx = 0; field_idx < m_fields.size(); ++field_idx )
163 if( m_allow_rejustify )
170 if( m_align_to_grid )
172 pos.
x =
round_n( pos.
x, 50, field_side.
x >= 0 );
173 pos.
y =
round_n( pos.
y, 50, field_side.
y == 1 );
188 int max_field_width = 0;
189 int total_height = 0;
205 field_width = field->GetBoundingBox().GetWidth();
206 field_height = field->GetBoundingBox().GetHeight();
208 max_field_width =
std::max( max_field_width, field_width );
217 return wxSize( max_field_width, total_height );
235 wxFAIL_MSG(
"Invalid pin orientation" );
247 unsigned pin_count = 0;
249 std::vector<LIB_PIN*>
pins;
252 for(
LIB_PIN* each_pin : pins )
272 wxASSERT_MSG( m_screen,
"get_possible_colliders() with null m_screen" );
275 if(
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( item ) )
277 if( comp == m_component )
continue;
279 std::vector<SCH_FIELD*> fields;
280 comp->GetFields( fields,
true );
282 aItems.push_back( field );
284 aItems.push_back( item );
296 std::vector<SCH_ITEM*> filtered;
300 if(
SCH_COMPONENT* item_comp = dynamic_cast<SCH_COMPONENT*>( item ) )
301 item_box = item_comp->GetBodyBoundingBox();
303 item_box = item->GetBoundingBox();
306 filtered.push_back( item );
325 std::vector<SIDE_AND_NPINS> sides( sides_init, sides_init +
DIM( sides_init ) );
328 int orient_angle = orient & 0xff;
331 double w = double( m_comp_bbox.
GetWidth() );
332 double h = double( m_comp_bbox.
GetHeight() );
340 switch( orient_angle )
343 std::swap( sides[0], sides[1] );
344 std::swap( sides[1], sides[3] );
348 std::swap( sides[0], sides[2] );
349 std::swap( sides[1], sides[2] );
353 std::swap( sides[0], sides[3] );
357 std::swap( sides[1], sides[2] );
367 std::swap( sides[0], sides[2] );
373 std::swap( sides[0], sides[1] );
374 std::swap( sides[1], sides[3] );
389 std::vector<SIDE> sides( sides_init, sides_init +
DIM( sides_init ) );
390 std::vector<SIDE_AND_COLL> colliding;
393 for( SIDE
side : sides )
401 if( line && !
side.
x )
414 colliding.push_back( {
side, collision } );
427 const std::vector<SIDE_AND_COLL>& aCollidingSides,
COLLISION aCollision,
432 std::vector<SIDE_AND_NPINS>::iterator it = aSides.begin();
433 while( it != aSides.end() )
438 if( collision.side == it->side && collision.collision == aCollision )
445 if( it->pins <= sel.
pins )
450 it = aSides.erase( it );
470 if( aAvoidCollisions )
477 for(
SIDE_AND_NPINS& each_side : sides | boost::adaptors::reversed )
479 if( !each_side.pins )
return each_side.side;
484 if( each_side.pins <= side.pins )
486 side.pins = each_side.pins;
487 side.side = each_side.side;
518 int offs_x = ( m_comp_bbox.
GetWidth() + m_fbox_size.GetWidth() ) / 2 +
HPADDING;
519 int offs_y = ( m_comp_bbox.
GetHeight() + m_fbox_size.GetHeight() ) / 2 +
VPADDING;
521 fbox_center.
x += aFieldSide.
x * offs_x;
522 fbox_center.
y += aFieldSide.
y * offs_y;
525 fbox_center.
x - m_fbox_size.GetWidth() / 2,
526 fbox_center.
y - m_fbox_size.GetHeight() / 2 );
539 if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM )
543 if( colliders.empty() )
555 if( start.
y != end.y )
560 offset = this_offset;
561 else if( offset != this_offset )
572 if( aSide == SIDE_BOTTOM )
608 switch( field_hjust )
611 field_xcoord = aFieldBox.
GetLeft();
614 field_xcoord = aFieldBox.
Centre().
x;
617 field_xcoord = aFieldBox.
GetRight();
620 wxFAIL_MSG(
"Unexpected value for SCH_FIELD::GetHorizJustify()" );
621 field_xcoord = aFieldBox.
Centre().
x;
657 int placement = *aPosAccum + padding / 2 + field_height / 2;
659 *aPosAccum += padding + field_height;
670 if( m_align_to_grid )
692 if( aEvent.GetInt() == 0 )
696 *aEvent.GetClientObject() );
707 if( !component->
IsNew() )
712 GetCanvas()->Refresh();
720 wxASSERT_MSG( aScreen,
"A SCH_SCREEN pointer must be given for manual autoplacement" );
723 m_fieldsAutoplaced = ( aManual? AUTOPLACED_MANUAL : AUTOPLACED_AUTO );
void justify_field(SCH_FIELD *aField, SIDE aFieldSide)
Function justify_field Set the justification of a field based on the side it's supposed to be on...
#define DIM(x)
of elements in an array
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
wxSize ComputeFBoxSize(bool aDynamic)
Compute and return the size of the fields' bounding box.
STATUS_FLAGS GetFlags() const
unsigned pins_on_side(SIDE aSide)
Function pins_on_side Count the number of pins on a side of the component.
std::vector< SCH_FIELD * > m_fields
TRANSFORM & GetTransform() const
std::vector< SIDE_AND_COLL > get_colliding_sides()
Function get_colliding_sides Return a list of the sides where a field set would collide with another ...
int GetOrientation()
Get the display symbol orientation.
bool collide(T aObject, U aAnotherObject, int aMinDistance)
collide template method
SCH_COMPONENT * m_component
SIDE_AND_NPINS choose_side_filtered(std::vector< SIDE_AND_NPINS > &aSides, const std::vector< SIDE_AND_COLL > &aCollidingSides, COLLISION aCollision, SIDE_AND_NPINS aLastSelection)
Function choose_side_filtered Choose a side for the fields, filtered on only one side collision type...
wxPoint field_box_placement(SIDE aFieldSide)
Function field_box_placement Returns the position of the field bounding box.
void SetOrigin(const wxPoint &pos)
wxPoint GetEndPoint() const
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the fields.
static const KICAD_T MovableItems[]
A scan list for all movable schematic items.
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
T round_n(const T &value, const T &n, bool aRoundUp)
Function round_n Round up/down to the nearest multiple of n.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
#define FIELD_PADDING_ALIGNED
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
bool fit_fields_between_wires(EDA_RECT *aBox, SIDE aSide)
Function fit_fields_between_wires Shift a field box up or down a bit to make the fields fit between s...
int field_horiz_placement(SCH_FIELD *aField, const EDA_RECT &aFieldBox)
Function field_horiz_placement Place a field horizontally, taking into account the field width and ju...
wxPoint GetStartPoint() const
Class EDA_HOTKEY_CLIENT_DATA provides client data member for hotkeys to include in command events gen...
static const SIDE SIDE_LEFT
const wxChar AutoplaceAlignEntry[]
std::vector< SCH_ITEM * > m_colliders
SCH_ITEM * GetCurItem() const
Return the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
Class LIB_ITEM definition.
int field_vert_placement(SCH_FIELD *aField, const EDA_RECT &aFieldBox, int *aPosAccum, bool aDynamic)
Function field_vert_placement Place a field vertically.
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
wxConfigBase * KifaceSettings() const
void OnAutoplaceFields(wxCommandEvent &aEvent)
Handle the ID_AUTOPLACE_FIELDS event.
EDA_TEXT_HJUSTIFY_T TO_HJUSTIFY(int x)
Function TO_HJUSTIFY Converts an integer to a horizontal justification; neg=L zero=C pos=R...
const wxPoint GetPosition() const
static const SIDE SIDE_RIGHT
SIDE get_pin_side(LIB_PIN *aPin)
Function get_pin_side Return the side that a pin is on.
SCH_ITEM * GetDrawItems() const
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Definition the SCH_COMPONENT class for Eeschema.
void GetPins(std::vector< LIB_PIN * > &aPinsList)
Populate a vector with all the pins.
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual)
Automatically orient all the fields in the component.
Segment description base class to describe items which have 2 end points (track, wire, draw line ...)
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
static const SIDE SIDE_BOTTOM
int get_field_padding()
Function get_field_padding Return the desired padding between fields.
void SetCurItem(SCH_ITEM *aItem)
Sets the currently selected object, m_CurrentItem.
Class EDA_RECT handles the component boundary box.
Class SCH_COMPONENT describes a real schematic component.
static void reverse(privcurve_t *curve)
bool IsHorizJustifyFlipped() const
Function IsHorizJustifyFlipped Returns whether the field will be rendered with the horizontal justifi...
SIDE choose_side_for_fields(bool aAvoidCollisions)
Function choose_side_for_fields Look where a component's pins are to pick a side to put the fields on...
void DoAutoplace(bool aManual)
Do the actual autoplacement.
Some functions to handle hotkeys in KiCad.
static const SIDE SIDE_TOP
std::vector< SIDE_AND_NPINS > get_preferred_sides()
Function get_preferred_sides Return a list with the preferred field sides for the component...
AUTOPLACER(SCH_COMPONENT *aComponent, SCH_SCREEN *aScreen)
void get_possible_colliders(std::vector< SCH_ITEM * > &aItems)
Function get_possible_colliders Populate a list of all drawing items that may collide with the fields...
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
const wxChar AutoplaceJustifyEntry[]
int PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
std::vector< SCH_ITEM * > filtered_colliders(const EDA_RECT &aRect)
Function filtered_colliders Filter a list of possible colliders to include only those that actually c...