← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] Eeschema: make field autoplace grid flexible with field height

 

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 <cpavlin1@xxxxxxxxxxxxxx>
>> 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     : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help   : https://help.launchpad.net/ListHelp
> 


References