Pcbnew: Better selection of corners and edges in zones. Usefull when selecting edge/corner by right clicking on a zone outline, for hight density boards.
This commit is contained in:
parent
e39522975a
commit
cdffc3d15f
|
@ -794,9 +794,9 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in
|
|||
*/
|
||||
bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
|
||||
{
|
||||
if( HitTestForCorner( refPos ) >= 0 )
|
||||
if( HitTestForCorner( refPos ) )
|
||||
return true;
|
||||
if( HitTestForEdge( refPos ) >= 0 )
|
||||
if( HitTestForEdge( refPos ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -807,34 +807,40 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
|
|||
* Function HitTestForCorner
|
||||
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
|
||||
* Choose the nearest corner
|
||||
* "near" means CORNER_MIN_DIST_IN_PIXELS pixels
|
||||
* @return -1 if none, corner index in .corner <vector>
|
||||
* "near" means grid size (or CORNER_MIN_DIST if grid is not known)
|
||||
* Set m_CornerSelection to corner index in .m_Poly->corner or -1 if no corner found
|
||||
* @return true if a corner found
|
||||
* @param refPos : A wxPoint to test
|
||||
*/
|
||||
int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
||||
bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
||||
{
|
||||
#define CORNER_MIN_DIST 500 // distance (in internal units) to detect a corner in a zone outline
|
||||
int dist, min_dist;
|
||||
unsigned item_pos, lim;
|
||||
lim = m_Poly->corner.size();
|
||||
m_CornerSelection = -1;
|
||||
m_CornerSelection = -1; // Set to not found
|
||||
|
||||
min_dist = CORNER_MIN_DIST;
|
||||
for( item_pos = 0; item_pos < lim; item_pos++ )
|
||||
#define CORNER_MIN_DIST 100 // distance (in internal units) to detect a corner in a zone outline
|
||||
int min_dist = CORNER_MIN_DIST + 1;
|
||||
if( GetBoard() && GetBoard()->m_PcbFrame )
|
||||
{
|
||||
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs(
|
||||
m_Poly->corner[item_pos].y - refPos.y );
|
||||
if( dist <= min_dist )
|
||||
// Use grid size because it is known
|
||||
wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid();
|
||||
min_dist = wxRound( MIN( grid.x, grid.y ) );
|
||||
}
|
||||
|
||||
wxPoint delta;
|
||||
unsigned lim = m_Poly->corner.size();
|
||||
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
|
||||
{
|
||||
delta.x = refPos.x - m_Poly->corner[item_pos].x;
|
||||
delta.y = refPos.y - m_Poly->corner[item_pos].y;
|
||||
// Calculate a distance:
|
||||
int dist = MAX( abs( delta.x ), abs( delta.y ) );
|
||||
if( dist < min_dist ) // this corner is a candidate:
|
||||
{
|
||||
m_CornerSelection = item_pos;
|
||||
min_dist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_CornerSelection >= 0 )
|
||||
return item_pos;
|
||||
|
||||
return -1;
|
||||
return m_CornerSelection >= 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -842,25 +848,31 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
|||
* Function HitTestForEdge
|
||||
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
|
||||
* choose the nearest segment
|
||||
* "near" means EDGE_MIN_DIST_IN_PIXELS pixels
|
||||
* @return -1 if none, or index of the starting corner in .corner <vector>
|
||||
* "near" means grid size (or EDGE_MIN_DIST if grid is not known)
|
||||
* Set m_CornerSelection to -1 if nothing found, or index of the starting corner of edge
|
||||
* in .m_Poly->corner
|
||||
* @return true if found
|
||||
* @param refPos : A wxPoint to test
|
||||
*/
|
||||
int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||
bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||
{
|
||||
unsigned lim = m_Poly->corner.size();
|
||||
|
||||
m_CornerSelection = -1; // Set to not found
|
||||
|
||||
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
|
||||
int dist, min_dist;
|
||||
unsigned item_pos, lim;
|
||||
lim = m_Poly->corner.size();
|
||||
|
||||
/* Test for an entire segment */
|
||||
unsigned first_corner_pos = 0, end_segm;
|
||||
m_CornerSelection = -1;
|
||||
min_dist = EDGE_MIN_DIST;
|
||||
|
||||
for( item_pos = 0; item_pos < lim; item_pos++ )
|
||||
int min_dist = EDGE_MIN_DIST+1;
|
||||
if( GetBoard() && GetBoard()->m_PcbFrame )
|
||||
{
|
||||
end_segm = item_pos + 1;
|
||||
// Use grid size because it is known
|
||||
wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid();
|
||||
min_dist = wxRound( MIN( grid.x, grid.y ) );
|
||||
}
|
||||
|
||||
unsigned first_corner_pos = 0;
|
||||
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
|
||||
{
|
||||
unsigned end_segm = item_pos + 1;
|
||||
|
||||
/* the last corner of the current outline is tested
|
||||
* the last segment of the current outline starts at current corner, and ends
|
||||
|
@ -874,23 +886,20 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
|||
}
|
||||
|
||||
/* test the dist between segment and ref point */
|
||||
dist = (int) GetPointToLineSegmentDistance( refPos.x,
|
||||
int dist = (int) GetPointToLineSegmentDistance( refPos.x,
|
||||
refPos.y,
|
||||
m_Poly->corner[item_pos].x,
|
||||
m_Poly->corner[item_pos].y,
|
||||
m_Poly->corner[end_segm].x,
|
||||
m_Poly->corner[end_segm].y );
|
||||
if( dist <= min_dist )
|
||||
if( dist < min_dist )
|
||||
{
|
||||
m_CornerSelection = item_pos;
|
||||
min_dist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_CornerSelection >= 0 )
|
||||
return item_pos;
|
||||
|
||||
return -1;
|
||||
return m_CornerSelection >= 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -242,19 +242,21 @@ public:
|
|||
|
||||
/**
|
||||
* Function HitTestForCorner
|
||||
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
|
||||
* @return -1 if none, corner index in .corner <vector>
|
||||
* tests if the given wxPoint near a corner
|
||||
* Set m_CornerSelection to -1 if nothing found, or index of corner
|
||||
* @return true if found
|
||||
* @param refPos : A wxPoint to test
|
||||
*/
|
||||
int HitTestForCorner( const wxPoint& refPos );
|
||||
bool HitTestForCorner( const wxPoint& refPos );
|
||||
|
||||
/**
|
||||
* Function HitTestForEdge
|
||||
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
|
||||
* @return -1 if none, or index of the starting corner in .corner <vector>
|
||||
* tests if the given wxPoint is near a segment defined by 2 corners.
|
||||
* Set m_CornerSelection to -1 if nothing found, or index of the starting corner of vertice
|
||||
* @return true if found
|
||||
* @param refPos : A wxPoint to test
|
||||
*/
|
||||
int HitTestForEdge( const wxPoint& refPos );
|
||||
bool HitTestForEdge( const wxPoint& refPos );
|
||||
|
||||
/**
|
||||
* Function HitTest (overlayed)
|
||||
|
|
|
@ -256,7 +256,7 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
// We have a hit under mouse (a zone outline corner or segment)
|
||||
// test for a corner only because want to move corners only.
|
||||
ZONE_CONTAINER* edge_zone = (ZONE_CONTAINER*) DrawStruct;
|
||||
if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) >= 0 ) // corner located!
|
||||
if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) // corner located!
|
||||
hit_on_corner = true;
|
||||
}
|
||||
if( hit_on_corner )
|
||||
|
|
|
@ -567,15 +567,14 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
|
|||
|
||||
ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu,
|
||||
-1, _( "Zones" ), add_zone_xpm );
|
||||
int index;
|
||||
if( ( index = edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) >= 0 )
|
||||
if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) )
|
||||
{
|
||||
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
|
||||
_( "Move Corner" ), move_xpm );
|
||||
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
|
||||
_( "Delete Corner" ), delete_xpm );
|
||||
}
|
||||
else if( ( index = edge_zone->HitTestForEdge( GetScreen()->RefPos( true ) ) ) >= 0 )
|
||||
else if( edge_zone->HitTestForEdge( GetScreen()->RefPos( true ) ) )
|
||||
{
|
||||
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
|
||||
_( "Create Corner" ), add_corner_xpm );
|
||||
|
@ -610,7 +609,8 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
|
|||
msg, edit_xpm );
|
||||
|
||||
zones_menu->AppendSeparator();
|
||||
if( index >= 0 && edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) )
|
||||
if( edge_zone->m_CornerSelection >= 0 &&
|
||||
edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) )
|
||||
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
|
||||
_( "Delete Cutout" ), delete_xpm );
|
||||
|
||||
|
|
Loading…
Reference in New Issue