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 )
|
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 <vector>
|
* 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
|
* @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;
|
|
||||||
lim = m_Poly->corner.size();
|
|
||||||
m_CornerSelection = -1;
|
|
||||||
|
|
||||||
min_dist = CORNER_MIN_DIST;
|
#define CORNER_MIN_DIST 100 // distance (in internal units) to detect a corner in a zone outline
|
||||||
for( item_pos = 0; item_pos < lim; item_pos++ )
|
int min_dist = CORNER_MIN_DIST + 1;
|
||||||
|
if( GetBoard() && GetBoard()->m_PcbFrame )
|
||||||
{
|
{
|
||||||
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs(
|
// Use grid size because it is known
|
||||||
m_Poly->corner[item_pos].y - refPos.y );
|
wxRealPoint grid = GetBoard()->m_PcbFrame->DrawPanel->GetGrid();
|
||||||
if( dist <= min_dist )
|
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;
|
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 <vector>
|
* 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
|
* @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
|
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
|
||||||
int dist, min_dist;
|
int min_dist = EDGE_MIN_DIST+1;
|
||||||
unsigned item_pos, lim;
|
if( GetBoard() && GetBoard()->m_PcbFrame )
|
||||||
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++ )
|
|
||||||
{
|
{
|
||||||
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 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 <vector>
|
* 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 <vector>
|
* 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 )
|
||||||
// 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
|
||||||
|
|
||||||
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 );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue