Field spacing is much nicer with this patch so I committed in the product branch r6381. Thanks.
On 12/15/2015 5:30 PM, Chris Pavlina wrote: > #6377 changed a bit in the vicinity of this patch, so here's an updated one > to preempt any merge conflicts. > > On Sun, Dec 13, 2015 at 12:53:53PM -0500, Chris Pavlina wrote: >> Okay, here's a patch to make the autoplacement grid for fields flexible, >> so fields are positioned sanely when they have different heights. Just >> finished this an hour ago, as opposed to the main autoplacement patch >> which got months of testing, so somebody else might want to try this >> out. >> >> I'm going to prepare one more patch, to handle a slightly quirky field >> placement in a specific arrangement with a long component symbol >> sandwiched between wires. That should be it. >> >> -- >> Chris > >> commit b8fdf66034c0028ae33a3d372937279919427916 >> Author: Chris Pavlina <[email protected]> >> Date: Sat Dec 12 16:29:19 2015 -0500 >> >> Make vertical autoplacement grid flexible >> >> diff --git a/eeschema/autoplace_fields.cpp b/eeschema/autoplace_fields.cpp >> index 001127a..5849309 100644 >> --- a/eeschema/autoplace_fields.cpp >> +++ b/eeschema/autoplace_fields.cpp >> @@ -63,9 +63,11 @@ >> #include <vector> >> #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 VPADDING 50 >> +#define VPADDING 25 >> >> /** >> * Function round_n >> @@ -127,7 +129,7 @@ public: >> Kiface().KifaceSettings()->Read( AUTOPLACE_ALIGN_KEY, >> &m_align_to_grid, false ); >> >> m_comp_bbox = m_component->GetBodyBoundingBox(); >> - m_fbox_size = ComputeFBoxSize(); >> + m_fbox_size = ComputeFBoxSize( /* aDynamic */ true ); >> >> m_power_symbol = ! m_component->IsInNetlist(); >> >> @@ -143,17 +145,16 @@ public: >> */ >> void DoAutoplace( bool aManual ) >> { >> + bool force_wire_spacing = false; >> SIDE field_side = choose_side_for_fields( aManual ); >> wxPoint fbox_pos = field_box_placement( field_side ); >> EDA_RECT field_box( fbox_pos, m_fbox_size ); >> >> if( aManual ) >> - { >> - fbox_pos = fit_fields_between_wires( field_box, field_side ); >> - field_box.SetOrigin( fbox_pos ); >> - } >> + force_wire_spacing = fit_fields_between_wires( &field_box, >> field_side ); >> >> // Move the fields >> + int last_y_coord = field_box.GetTop(); >> for( int field_idx = 0; field_idx < m_fields.size(); ++field_idx ) >> { >> SCH_FIELD* field = m_fields[field_idx]; >> @@ -163,7 +164,7 @@ public: >> >> wxPoint pos( >> 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 ) >> { >> @@ -179,29 +180,40 @@ public: >> protected: >> /** >> * 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 total_height = 0; >> + >> BOOST_FOREACH( SCH_FIELD* field, m_fields ) >> { >> int field_width; >> + int field_height; >> >> if( m_component->GetTransform().y1 ) >> { >> field->SetOrientation( TEXT_ORIENT_VERT ); >> - field_width = field->GetBoundingBox().GetHeight(); >> } >> else >> { >> 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 ); >> + >> + 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 >> * 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 ) >> - return aBox.GetPosition(); >> + return false; >> >> - std::vector<SCH_ITEM*> colliders = filtered_colliders( aBox ); >> + std::vector<SCH_ITEM*> colliders = filtered_colliders( *aBox ); >> if( colliders.empty() ) >> - return aBox.GetPosition(); >> + return false; >> >> // Find the offset of the wires for proper positioning >> int offset = 0; >> @@ -537,24 +549,28 @@ protected: >> { >> SCH_LINE* line = dynamic_cast<SCH_LINE*>( item ); >> if( !line ) >> - return aBox.GetPosition(); >> + return false; >> wxPoint start = line->GetStartPoint(), end = >> line->GetEndPoint(); >> 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 ) >> offset = this_offset; >> else if( offset != this_offset ) >> - return aBox.GetPosition(); >> + return false; >> } >> >> if( aSide == SIDE_TOP ) >> offset = -offset; >> >> - wxPoint pos = aBox.GetPosition(); >> - pos.y = round_n( pos.y - offset, FIELD_V_SPACING, aSide == >> SIDE_BOTTOM ) + offset; >> - return pos; >> + wxPoint pos = aBox->GetPosition(); >> + pos.y = round_n( pos.y - offset, WIRE_V_SPACING, aSide == >> SIDE_BOTTOM ) + offset; >> + >> + // Compensate for padding >> + pos.y += WIRE_V_SPACING / 2; >> + aBox->SetOrigin( pos ); >> + return true; >> } >> >> >> @@ -597,6 +613,59 @@ protected: >> 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 ); > > > > _______________________________________________ > Mailing list: https://launchpad.net/~kicad-developers > Post to : [email protected] > Unsubscribe : https://launchpad.net/~kicad-developers > More help : https://help.launchpad.net/ListHelp > _______________________________________________ Mailing list: https://launchpad.net/~kicad-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~kicad-developers More help : https://help.launchpad.net/ListHelp

