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

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
Loading
Loading
Loading
Loading
+47 −38
Original line number Original line Diff line number Diff line
@@ -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 )
 * 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 )
 * 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 )
        }
        }


        /* 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;
}
}




+8 −6
Original line number Original line Diff line number Diff line
@@ -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)
+1 −1
Original line number Original line Diff line number Diff line
@@ -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 )
+4 −4
Original line number Original line Diff line number Diff line
@@ -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
                      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 );