7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Fix error-marker highlighting for multiple markers at the same location

Previously, if multiple error markers were placed at the same location,
the selected marker was not visually differentiated from the unselected
ones, even if one was at the top of the stack. To fix this, Need to pass
overlapping markers to the FocusOnItems() function instead of calling
FocusOnItem() with only the selected marker.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/9778
This commit is contained in:
Dhinesh 2024-10-26 14:31:50 +05:30 committed by Seth Hillbrand
parent 373d9c9281
commit e02b6be4c9
4 changed files with 68 additions and 2 deletions

View File

@ -300,6 +300,8 @@ ADVANCED_CFG::ADVANCED_CFG()
m_MaximumThreads = 0;
m_MinimumMarkerSeparationDistance = 0.15;
loadFromConfigFile();
}

View File

@ -731,6 +731,15 @@ public:
*/
int m_MaximumThreads;
/**
* When finding overlapped marker a minium distance (in mm) between two DRC markers required
* to mark it as overlapped
*
* Setting name: "MinimumMarkerSeparationDistance"
* Default value: 0.15
*/
double m_MinimumMarkerSeparationDistance;
///@}
private:

View File

@ -55,6 +55,7 @@
#include <tools/zone_filler_tool.h>
#include <tools/board_inspection_tool.h>
#include <kiplatform/ui.h>
#include <advanced_config.h>
// wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
// not, in repeatedly creating/destroying a wxDC to do the measurement in).
@ -400,6 +401,38 @@ void DIALOG_DRC::UpdateData()
}
/**
* @brief Checks if two board items are overlapping.
*
* This function determines if the selected marker item and the unselected marker item
* are overlapping based on their positions. Overlapping is defined by their positions being
* equal or by the distance between them being less than a specified minimum difference.
*
* @param aSelectedMarkerItem Pointer to the selected board item.
* @param aUnSelectedMarkerItem Pointer to the unselected board item.
* @return true if the items are overlapping, false otherwise.
*/
bool IsOverlapping( BOARD_ITEM* aSelectedMarkerItem, BOARD_ITEM* aUnSelectedMarkerItem )
{
double selectedItemX = (double) aSelectedMarkerItem->GetX() / PCB_IU_PER_MM;
double selectedItemY = (double) aSelectedMarkerItem->GetY() / PCB_IU_PER_MM;
double unSelectedItemX = (double) aUnSelectedMarkerItem->GetX() / PCB_IU_PER_MM;
double unSelectedItemY = (double) aUnSelectedMarkerItem->GetY() / PCB_IU_PER_MM;
double xDiff = selectedItemX > unSelectedItemX ? selectedItemX - unSelectedItemX
: unSelectedItemX - selectedItemX;
double yDiff = selectedItemY > unSelectedItemY ? selectedItemY - unSelectedItemY
: unSelectedItemY - selectedItemY;
double minimumMarkerSeparationDistance =
ADVANCED_CFG::GetCfg().m_MinimumMarkerSeparationDistance;
return ( selectedItemX == unSelectedItemX && selectedItemY == unSelectedItemY )
|| ( xDiff < minimumMarkerSeparationDistance && yDiff < minimumMarkerSeparationDistance )
|| ( xDiff < minimumMarkerSeparationDistance && selectedItemY == unSelectedItemY )
|| ( yDiff < minimumMarkerSeparationDistance && selectedItemX == unSelectedItemX );
}
void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
{
BOARD* board = m_frame->GetBoard();
@ -596,7 +629,25 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
}
else
{
m_frame->FocusOnItem( item, principalLayer );
if( item->Type() == PCB_MARKER_T )
{
std::vector<BOARD_ITEM*> items;
for( BOARD_ITEM* boardMarkerItem : board->Markers() )
{
if( item->m_Uuid != boardMarkerItem->m_Uuid && IsOverlapping( item, boardMarkerItem ) )
{
items.push_back( boardMarkerItem );
}
}
items.push_back( item );
m_frame->FocusOnItems( items, principalLayer );
}
else
{
m_frame->FocusOnItem( item, principalLayer );
}
}
aEvent.Skip();

View File

@ -365,12 +365,16 @@ void PCB_BASE_FRAME::FocusOnItems( std::vector<BOARD_ITEM*> aItems, PCB_LAYER_ID
break;
case PCB_PAD_T:
case PCB_MARKER_T:
case PCB_VIA_T:
FocusOnLocation( item->GetFocusPosition() );
GetCanvas()->Refresh();
return;
case PCB_MARKER_T:
FocusOnLocation( item->GetFocusPosition() );
GetCanvas()->Refresh();
break;
case PCB_SHAPE_T:
case PCB_FIELD_T:
case PCB_TEXT_T: