Don't allow point editor inversion when editing pad shapes.
Fixes https://gitlab.com/kicad/code/kicad/issues/5272
This commit is contained in:
parent
5589cdf921
commit
631b5a9340
|
@ -472,6 +472,99 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the coordinates of 4 corners of a rectangle, accordint to constraints
|
||||||
|
* and the moved corner
|
||||||
|
* @param aEditedPointIndex is the corner id
|
||||||
|
* @param minWidth is the minimal width constraint
|
||||||
|
* @param minHeight is the minimal height constraint
|
||||||
|
* @param topLeft is the RECT_TOPLEFT to constraint
|
||||||
|
* @param topRight is the RECT_TOPRIGHT to constraint
|
||||||
|
* @param botLeft is the RECT_BOTLEFT to constraint
|
||||||
|
* @param botRight is the RECT_BOTRIGHT to constraint
|
||||||
|
* @param aGridSize is the a constraint: if > 1 new coordinates are on this grid
|
||||||
|
*/
|
||||||
|
static void pinEditedCorner( int aEditedPointIndex, int minWidth, int minHeight,
|
||||||
|
VECTOR2I& topLeft, VECTOR2I& topRight,
|
||||||
|
VECTOR2I& botLeft, VECTOR2I& botRight,
|
||||||
|
int aGridSize = 0 )
|
||||||
|
{
|
||||||
|
// A macro to keep a coordinate on the grid:
|
||||||
|
#define MOVE_TO_GRID(z) { z.x = ( (z.x +1 ) / aGridSize ) * aGridSize;\
|
||||||
|
z.y = ( (z.y +1 ) / aGridSize ) * aGridSize; }
|
||||||
|
switch( aEditedPointIndex )
|
||||||
|
{
|
||||||
|
case RECT_TOP_LEFT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
topLeft.x = std::min( topLeft.x, botRight.x - minWidth );
|
||||||
|
topLeft.y = std::min( topLeft.y, botRight.y - minHeight );
|
||||||
|
|
||||||
|
if( aGridSize > 1 ) // Keep point on specified grid size
|
||||||
|
{
|
||||||
|
topLeft.x = ( topLeft.x / aGridSize ) * aGridSize;
|
||||||
|
topLeft.y = ( topLeft.y / aGridSize ) * aGridSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
topRight.y = topLeft.y;
|
||||||
|
botLeft.x = topLeft.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_TOP_RIGHT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
topRight.x = std::max( topRight.x, botLeft.x + minWidth );
|
||||||
|
topRight.y = std::min( topRight.y, botLeft.y - minHeight );
|
||||||
|
|
||||||
|
if( aGridSize > 1 ) // Keep point on specified grid size
|
||||||
|
{
|
||||||
|
topRight.x = ( ( topRight.x+1 ) / aGridSize ) * aGridSize;
|
||||||
|
topRight.y = ( topRight.y / aGridSize ) * aGridSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
topLeft.y = topRight.y;
|
||||||
|
botRight.x = topRight.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_BOT_LEFT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
botLeft.x = std::min( botLeft.x, topRight.x - minWidth );
|
||||||
|
botLeft.y = std::max( botLeft.y, topRight.y + minHeight );
|
||||||
|
|
||||||
|
if( aGridSize > 1 ) // Keep point on specified grid size
|
||||||
|
{
|
||||||
|
botLeft.x = ( botLeft.x / aGridSize ) * aGridSize;
|
||||||
|
botLeft.y = ( ( botLeft.y+1 ) / aGridSize ) * aGridSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
botRight.y = botLeft.y;
|
||||||
|
topLeft.x = botLeft.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECT_BOT_RIGHT:
|
||||||
|
// pin edited point within opposite corner
|
||||||
|
botRight.x = std::max( botRight.x, topLeft.x + minWidth );
|
||||||
|
botRight.y = std::max( botRight.y, topLeft.y + minHeight );
|
||||||
|
|
||||||
|
if( aGridSize > 1 ) // Keep point on specified grid size
|
||||||
|
{
|
||||||
|
botRight.x = ( ( botRight.x+1 ) / aGridSize ) * aGridSize;
|
||||||
|
botRight.y = ( ( botRight.y+1 ) / aGridSize ) * aGridSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push edited point edges to adjacent corners
|
||||||
|
botLeft.y = botRight.y;
|
||||||
|
topRight.x = botRight.x;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void POINT_EDITOR::updateItem() const
|
void POINT_EDITOR::updateItem() const
|
||||||
{
|
{
|
||||||
EDA_ITEM* item = m_editPoints->GetParent();
|
EDA_ITEM* item = m_editPoints->GetParent();
|
||||||
|
@ -873,6 +966,14 @@ void POINT_EDITOR::updateItem() const
|
||||||
case PAD_SHAPE_ROUNDRECT:
|
case PAD_SHAPE_ROUNDRECT:
|
||||||
case PAD_SHAPE_CHAMFERED_RECT:
|
case PAD_SHAPE_CHAMFERED_RECT:
|
||||||
{
|
{
|
||||||
|
VECTOR2I topLeft = m_editPoints->Point( RECT_TOP_LEFT ).GetPosition();
|
||||||
|
VECTOR2I topRight = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition();
|
||||||
|
VECTOR2I botLeft = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition();
|
||||||
|
VECTOR2I botRight = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition();
|
||||||
|
|
||||||
|
pinEditedCorner( getEditedPointIndex(), Mils2iu( 1 ), Mils2iu( 1 ),
|
||||||
|
topLeft, topRight, botLeft, botRight );
|
||||||
|
|
||||||
if( ( pad->GetOffset().x || pad->GetOffset().y )
|
if( ( pad->GetOffset().x || pad->GetOffset().y )
|
||||||
|| ( pad->GetDrillSize().x && pad->GetDrillSize().y ) )
|
|| ( pad->GetDrillSize().x && pad->GetDrillSize().y ) )
|
||||||
{
|
{
|
||||||
|
@ -884,17 +985,17 @@ void POINT_EDITOR::updateItem() const
|
||||||
if( isModified( m_editPoints->Point( RECT_TOP_LEFT ) )
|
if( isModified( m_editPoints->Point( RECT_TOP_LEFT ) )
|
||||||
|| isModified( m_editPoints->Point( RECT_BOT_RIGHT ) ) )
|
|| isModified( m_editPoints->Point( RECT_BOT_RIGHT ) ) )
|
||||||
{
|
{
|
||||||
dist[0] = center.x - m_editPoints->Point( RECT_TOP_LEFT ).GetPosition().x;
|
dist[0] = center.x - topLeft.x;
|
||||||
dist[1] = center.y - m_editPoints->Point( RECT_TOP_LEFT ).GetPosition().y;
|
dist[1] = center.y - topLeft.y;
|
||||||
dist[2] = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition().x - center.x;
|
dist[2] = botRight.x - center.x;
|
||||||
dist[3] = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition().y - center.y;
|
dist[3] = botRight.y - center.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dist[0] = center.x - m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().x;
|
dist[0] = center.x - botLeft.x;
|
||||||
dist[1] = center.y - m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().y;
|
dist[1] = center.y - topRight.y;
|
||||||
dist[2] = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().x - center.x;
|
dist[2] = topRight.x - center.x;
|
||||||
dist[3] = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().y - center.y;
|
dist[3] = botLeft.y - center.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize padSize( dist[0] + dist[2], dist[1] + dist[3] );
|
wxSize padSize( dist[0] + dist[2], dist[1] + dist[3] );
|
||||||
|
@ -917,17 +1018,17 @@ void POINT_EDITOR::updateItem() const
|
||||||
if( isModified( m_editPoints->Point( RECT_TOP_LEFT ) )
|
if( isModified( m_editPoints->Point( RECT_TOP_LEFT ) )
|
||||||
|| isModified( m_editPoints->Point( RECT_BOT_RIGHT ) ) )
|
|| isModified( m_editPoints->Point( RECT_BOT_RIGHT ) ) )
|
||||||
{
|
{
|
||||||
left = m_editPoints->Point( RECT_TOP_LEFT ).GetPosition().x;
|
left = topLeft.x;
|
||||||
top = m_editPoints->Point( RECT_TOP_LEFT ).GetPosition().y;
|
top = topLeft.y;
|
||||||
right = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition().x;
|
right = botRight.x;
|
||||||
bottom = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition().y;
|
bottom = botRight.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
left = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().x;
|
left = botLeft.x;
|
||||||
top = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().y;
|
top = topRight.y;
|
||||||
right = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition().x;
|
right = topRight.x;
|
||||||
bottom = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition().y;
|
bottom = botLeft.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize padSize( abs( right - left ), abs( bottom - top ) );
|
wxSize padSize( abs( right - left ), abs( bottom - top ) );
|
||||||
|
|
|
@ -113,6 +113,17 @@ private:
|
||||||
///> Sets the current point being edited. NULL means none.
|
///> Sets the current point being edited. NULL means none.
|
||||||
void setEditedPoint( EDIT_POINT* aPoint );
|
void setEditedPoint( EDIT_POINT* aPoint );
|
||||||
|
|
||||||
|
inline int getEditedPointIndex() const
|
||||||
|
{
|
||||||
|
for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i )
|
||||||
|
{
|
||||||
|
if( m_editedPoint == &m_editPoints->Point( i ) )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
///> Returns true if aPoint is the currently modified point.
|
///> Returns true if aPoint is the currently modified point.
|
||||||
inline bool isModified( const EDIT_POINT& aPoint ) const
|
inline bool isModified( const EDIT_POINT& aPoint ) const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue