diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index e3730e6118..ca78fcbf14 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -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; } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 042887899d..f98764b56f 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -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) diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index abafd68384..435913cbc9 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -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 ) diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index c272bfda45..d4754ec65a 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -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 );