Commit cdffc3d1 authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: Better selection of corners and edges in zones. Usefull when selecting...

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.
parent e3952297
...@@ -794,9 +794,9 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in ...@@ -794,9 +794,9 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in
*/ */
bool ZONE_CONTAINER::HitTest( const wxPoint& refPos ) bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
{ {
if( HitTestForCorner( refPos ) >= 0 ) if( HitTestForCorner( refPos ) )
return true; return true;
if( HitTestForEdge( refPos ) >= 0 ) if( HitTestForEdge( refPos ) )
return true; return true;
return false; return false;
...@@ -807,34 +807,40 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos ) ...@@ -807,34 +807,40 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
* Function HitTestForCorner * Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* Choose the nearest corner * Choose the nearest corner
* "near" means CORNER_MIN_DIST_IN_PIXELS pixels * "near" means grid size (or CORNER_MIN_DIST if grid is not known)
* @return -1 if none, corner index in .corner &ltvector&gt * Set m_CornerSelection to corner index in .m_Poly-&gtcorner or -1 if no corner found
* @return true if a corner found
* @param refPos : A wxPoint to test * @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 m_CornerSelection = -1; // Set to not found
int dist, min_dist;
unsigned item_pos, lim; #define CORNER_MIN_DIST 100 // distance (in internal units) to detect a corner in a zone outline
lim = m_Poly->corner.size(); int min_dist = CORNER_MIN_DIST + 1;
m_CornerSelection = -1; if( GetBoard() && GetBoard()->m_PcbFrame )
{
// Use grid size because it is known
wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid();
min_dist = wxRound( MIN( grid.x, grid.y ) );
}
min_dist = CORNER_MIN_DIST; wxPoint delta;
for( item_pos = 0; item_pos < lim; item_pos++ ) unsigned lim = m_Poly->corner.size();
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
{ {
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( delta.x = refPos.x - m_Poly->corner[item_pos].x;
m_Poly->corner[item_pos].y - refPos.y ); delta.y = refPos.y - m_Poly->corner[item_pos].y;
if( dist <= min_dist ) // 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; m_CornerSelection = item_pos;
min_dist = dist; min_dist = dist;
} }
} }
if( m_CornerSelection >= 0 ) return m_CornerSelection >= 0;
return item_pos;
return -1;
} }
...@@ -842,25 +848,31 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) ...@@ -842,25 +848,31 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
* Function HitTestForEdge * Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* choose the nearest segment * choose the nearest segment
* "near" means EDGE_MIN_DIST_IN_PIXELS pixels * "near" means grid size (or EDGE_MIN_DIST if grid is not known)
* @return -1 if none, or index of the starting corner in .corner &ltvector&gt * Set m_CornerSelection to -1 if nothing found, or index of the starting corner of edge
* in .m_Poly-&gtcorner
* @return true if found
* @param refPos : A wxPoint to test * @param refPos : A wxPoint to test
*/ */
int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
{ {
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline unsigned lim = m_Poly->corner.size();
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
/* Test for an entire segment */ m_CornerSelection = -1; // Set to not found
unsigned first_corner_pos = 0, end_segm;
m_CornerSelection = -1; #define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
min_dist = EDGE_MIN_DIST; int min_dist = EDGE_MIN_DIST+1;
if( GetBoard() && GetBoard()->m_PcbFrame )
{
// Use grid size because it is known
wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid();
min_dist = wxRound( MIN( grid.x, grid.y ) );
}
for( item_pos = 0; item_pos < lim; item_pos++ ) unsigned first_corner_pos = 0;
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
{ {
end_segm = item_pos + 1; unsigned end_segm = item_pos + 1;
/* the last corner of the current outline is tested /* the last corner of the current outline is tested
* the last segment of the current outline starts at current corner, and ends * the last segment of the current outline starts at current corner, and ends
...@@ -874,23 +886,20 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) ...@@ -874,23 +886,20 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
} }
/* test the dist between segment and ref point */ /* test the dist between segment and ref point */
dist = (int) GetPointToLineSegmentDistance( refPos.x, int dist = (int) GetPointToLineSegmentDistance( refPos.x,
refPos.y, refPos.y,
m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].x,
m_Poly->corner[item_pos].y, m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x, m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y ); m_Poly->corner[end_segm].y );
if( dist <= min_dist ) if( dist < min_dist )
{ {
m_CornerSelection = item_pos; m_CornerSelection = item_pos;
min_dist = dist; min_dist = dist;
} }
} }
if( m_CornerSelection >= 0 ) return m_CornerSelection >= 0;
return item_pos;
return -1;
} }
......
...@@ -242,19 +242,21 @@ public: ...@@ -242,19 +242,21 @@ public:
/** /**
* Function HitTestForCorner * Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint near a corner
* @return -1 if none, corner index in .corner &ltvector&gt * Set m_CornerSelection to -1 if nothing found, or index of corner
* @return true if found
* @param refPos : A wxPoint to test * @param refPos : A wxPoint to test
*/ */
int HitTestForCorner( const wxPoint& refPos ); bool HitTestForCorner( const wxPoint& refPos );
/** /**
* Function HitTestForEdge * Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint is near a segment defined by 2 corners.
* @return -1 if none, or index of the starting corner in .corner &ltvector&gt * 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 * @param refPos : A wxPoint to test
*/ */
int HitTestForEdge( const wxPoint& refPos ); bool HitTestForEdge( const wxPoint& refPos );
/** /**
* Function HitTest (overlayed) * Function HitTest (overlayed)
......
...@@ -256,7 +256,7 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -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) // We have a hit under mouse (a zone outline corner or segment)
// test for a corner only because want to move corners only. // test for a corner only because want to move corners only.
ZONE_CONTAINER* edge_zone = (ZONE_CONTAINER*) DrawStruct; 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; hit_on_corner = true;
} }
if( hit_on_corner ) if( hit_on_corner )
......
...@@ -567,15 +567,14 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu ...@@ -567,15 +567,14 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu, ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu,
-1, _( "Zones" ), add_zone_xpm ); -1, _( "Zones" ), add_zone_xpm );
int index; if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) )
if( ( index = edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) >= 0 )
{ {
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
_( "Move Corner" ), move_xpm ); _( "Move Corner" ), move_xpm );
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
_( "Delete Corner" ), delete_xpm ); _( "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, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
_( "Create Corner" ), add_corner_xpm ); _( "Create Corner" ), add_corner_xpm );
...@@ -610,7 +609,8 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu ...@@ -610,7 +609,8 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
msg, edit_xpm ); msg, edit_xpm );
zones_menu->AppendSeparator(); 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, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
_( "Delete Cutout" ), delete_xpm ); _( "Delete Cutout" ), delete_xpm );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment