ADDED: Cross-probe highlighting of bus members

Note: this is a basic implementation but it could be
improved once we include bus information in the netlist
and pcbnew can natively keep track of buses and nets
instead of just nets.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/4158
This commit is contained in:
Jon Evans 2020-05-24 13:30:23 -04:00
parent 4a8d5a2e6c
commit c7daf8a8f3
15 changed files with 169 additions and 48 deletions

View File

@ -27,6 +27,7 @@ using namespace KIGFX;
RENDER_SETTINGS::RENDER_SETTINGS() :
m_highlightNetcodes(),
m_printDC( nullptr )
{
// Set the default initial values
@ -36,7 +37,6 @@ RENDER_SETTINGS::RENDER_SETTINGS() :
m_highlightEnabled = false;
m_hiContrastEnabled = false;
m_hiContrastFactor = 0.2f; //TODO: Make this user-configurable
m_highlightNetcode = -1;
m_outlineWidth = 1;
m_worksheetLineWidth = 100000;
m_defaultPenWidth = 0;

View File

@ -367,6 +367,55 @@ void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
}
void SCH_EDIT_FRAME::SetCrossProbeConnection( const SCH_CONNECTION* aConnection )
{
if( !aConnection )
{
SendCrossProbeClearHighlight();
return;
}
if( aConnection->IsNet() )
{
SendCrossProbeNetName( aConnection->Name() );
return;
}
if( aConnection->Members().empty() )
return;
wxString nets = aConnection->Members()[0]->Name();
if( aConnection->Members().size() == 1 )
{
SendCrossProbeNetName( nets );
return;
}
// TODO: This could be replaced by just sending the bus name once we have bus contents
// included as part of the netlist sent from eeschema to pcbnew (and thus pcbnew can
// natively keep track of bus membership)
for( size_t i = 1; i < aConnection->Members().size(); i++ )
nets << "," << aConnection->Members()[i]->Name();
std::string packet = StrPrintf( "$NETS: \"%s\"", TO_UTF8( nets ) );
if( !packet.empty() )
{
if( Kiface().IsSingle() )
SendCommand( MSG_TO_PCB, packet.c_str() );
else
{
// Typically ExpressMail is going to be s-expression packets, but since
// we have existing interpreter of the cross probe packet on the other
// side in place, we use that here.
Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_CROSS_PROBE, packet, this );
}
}
}
void SCH_EDIT_FRAME::SendCrossProbeClearHighlight()
{
std::string packet = "$CLEAR\n";

View File

@ -377,6 +377,12 @@ public:
*/
void SendCrossProbeNetName( const wxString& aNetName );
/**
* Sends a connection (net or bus) to pcbnew for highlighting
* @param aConnection is the connection to highlight
*/
void SetCrossProbeConnection( const SCH_CONNECTION* aConnection );
/**
* Tells PcbNew to clear the existing highlighted net, if one exists
*/

View File

@ -860,7 +860,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
}
else
{
editFrame->SendCrossProbeNetName( conn->Name() );
editFrame->SetCrossProbeConnection( conn );
editFrame->SetStatusText( wxString::Format( _( "Highlighted net: %s" ),
UnescapeString( conn->Name() ) ) );
}

View File

@ -116,9 +116,9 @@ public:
* Returns netcode of currently highlighted net.
* @return Netcode of currently highlighted net.
*/
inline int GetHighlightNetCode() const
inline const std::set<int>& GetHighlightNetCodes() const
{
return m_highlightNetcode;
return m_highlightNetcodes;
}
/**
@ -129,10 +129,21 @@ public:
* @param aNetcode is optional and if specified, turns on higlighting only for the net with
* number given as the parameter.
*/
inline void SetHighlight( bool aEnabled, int aNetcode = -1, bool aHighlightItems = false )
inline void SetHighlight( bool aEnabled, int aNetcode = -1, bool aHighlightItems = false,
bool aMulti = false )
{
m_highlightEnabled = aEnabled;
m_highlightNetcode = aEnabled ? aNetcode : -1;
if( aEnabled )
{
if( !aMulti )
m_highlightNetcodes.clear();
m_highlightNetcodes.insert( aNetcode );
}
else
m_highlightNetcodes.clear();
m_highlightItems = aEnabled ? aHighlightItems : false;
}
@ -250,9 +261,9 @@ protected:
float m_hiContrastFactor; // Factor used for computing high contrast color
bool m_highlightEnabled; // Highlight display mode on/off
int m_highlightNetcode; // Net number that is displayed in highlight
// -1 means that there is no specific net, and whole active
// layer is highlighted
std::set<int> m_highlightNetcodes; // Set of net cods to be highlighted
bool m_highlightItems; // Highlight items with their HIGHLIGHT flags set
float m_highlightFactor; // Factor used for computing highlight color

View File

@ -1874,11 +1874,14 @@ void BOARD::ResetNetHighLight()
}
void BOARD::SetHighLightNet( int aNetCode )
void BOARD::SetHighLightNet( int aNetCode, bool aMulti )
{
if( m_highLight.m_netCode != aNetCode )
if( !m_highLight.m_netCodes.count( aNetCode ) )
{
m_highLight.m_netCode = aNetCode;
if( !aMulti )
m_highLight.m_netCodes.clear();
m_highLight.m_netCodes.insert( aNetCode );
InvokeListeners( &BOARD_LISTENER::OnBoardHighlightNetChanged, *this );
}
}

View File

@ -134,12 +134,12 @@ class HIGH_LIGHT_INFO
friend class BOARD;
protected:
int m_netCode; // net selected for highlight (-1 when no net selected )
bool m_highLightOn; // highlight active
std::set<int> m_netCodes; // net(s) selected for highlight (-1 when no net selected )
bool m_highLightOn; // highlight active
void Clear()
{
m_netCode = -1;
m_netCodes.clear();
m_highLightOn = false;
}
@ -378,15 +378,20 @@ public:
/**
* Function GetHighLightNetCode
* @return netcode of net to highlight (-1 when no net selected)
* @return the set of net codes that should be highlighted
*/
int GetHighLightNetCode() const { return m_highLight.m_netCode; }
const std::set<int>& GetHighLightNetCodes() const
{
return m_highLight.m_netCodes;
}
/**
* Function SetHighLightNet
* Select the netcode to be highlighted.
* @param aNetCode is the net to highlight
* @param aMulti is true if you want to add a highlighted net without clearing the old one
*/
void SetHighLightNet( int aNetCode );
void SetHighLightNet( int aNetCode, bool aMulti = false );
/**
* Function IsHighLightNetON

View File

@ -31,24 +31,25 @@
* Note: these ports must be enabled for firewall protection
*/
#include <fctsys.h>
#include <pgm_base.h>
#include <kiface_i.h>
#include <kiway_express.h>
#include <pcb_edit_frame.h>
#include <eda_dde.h>
#include <macros.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_zone.h>
#include <collectors.h>
#include <pcbnew.h>
#include <eda_dde.h>
#include <fctsys.h>
#include <kiface_i.h>
#include <kiway_express.h>
#include <macros.h>
#include <netlist_reader/pcb_netlist.h>
#include <tools/pcb_actions.h>
#include <tool/tool_manager.h>
#include <tools/selection_tool.h>
#include <pcb_edit_frame.h>
#include <pcb_painter.h>
#include <pcbnew.h>
#include <pgm_base.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/selection_tool.h>
#include <wx/tokenzr.h>
/* Execute a remote command send by Eeschema via a socket,
* port KICAD_PCB_PORT_SERVICE_NUMBER
@ -68,6 +69,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
char* idcmd;
char* text;
int netcode = -1;
bool multiHighlight = false;
MODULE* module = NULL;
D_PAD* pad = NULL;
BOARD* pcb = GetBoard();
@ -99,6 +101,39 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
SetMsgPanel( items );
}
}
if( strcmp( idcmd, "$NETS:" ) == 0 )
{
wxStringTokenizer netsTok = wxStringTokenizer( FROM_UTF8( text ), "," );
bool first = true;
while( netsTok.HasMoreTokens() )
{
NETINFO_ITEM* netinfo = pcb->FindNet( netsTok.GetNextToken() );
if( netinfo )
{
if( first )
{
// TODO: Once buses are included in netlist, show bus name
MSG_PANEL_ITEMS items;
netinfo->GetMsgPanelInfo( this, items );
SetMsgPanel( items );
first = false;
pcb->SetHighLightNet( netinfo->GetNet() );
renderSettings->SetHighlight( true, netinfo->GetNet() );
multiHighlight = true;
}
else
{
pcb->SetHighLightNet( netinfo->GetNet(), true );
renderSettings->SetHighlight( true, netinfo->GetNet(), false, true );
}
}
}
netcode = -1;
}
else if( strcmp( idcmd, "$PIN:" ) == 0 )
{
wxString pinName = FROM_UTF8( text );
@ -174,11 +209,19 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
else
m_toolManager->RunAction( PCB_ACTIONS::highlightItem, true, (void*) module );
}
else if( netcode > 0 )
else if( netcode > 0 || multiHighlight )
{
renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
if( !multiHighlight )
{
renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
pcb->SetHighLightNet( netcode );
}
else
{
// Just pick the first one for area calculation
netcode = *pcb->GetHighLightNetCodes().begin();
}
pcb->SetHighLightNet( netcode );
pcb->HighLightON();
auto merge_area = [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )

View File

@ -164,7 +164,9 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists()
// Populate the net filter list with net names
m_netFilter->SetBoard( m_brd );
m_netFilter->SetNetInfo( &m_brd->GetNetInfo() );
m_netFilter->SetSelectedNetcode( m_brd->GetHighLightNetCode() );
if( !m_brd->GetHighLightNetCodes().empty() )
m_netFilter->SetSelectedNetcode( *m_brd->GetHighLightNetCodes().begin() );
// Populate the netclass filter list with netclass names
wxArrayString netclassNames;

View File

@ -489,8 +489,8 @@ void DIALOG_SELECT_NET_FROM_LIST::OnBoardHighlightNetChanged( BOARD& aBoard )
{
if( !m_brd->IsHighLightNetON() )
m_netsList->UnselectAll();
else
HighlightNet( m_brd->FindNet( m_brd->GetHighLightNetCode() ) );
else if( !m_brd->GetHighLightNetCodes().empty() )
HighlightNet( m_brd->FindNet( *m_brd->GetHighLightNetCodes().begin() ) );
}

View File

@ -280,7 +280,7 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer
}
// Single net highlight mode
if( m_highlightEnabled && netCode == m_highlightNetcode )
if( m_highlightEnabled && m_highlightNetcodes.count( netCode ) )
return m_layerColorsHi[aLayer];
// Return grayish color for non-highlighted layers in the high contrast mode

View File

@ -75,7 +75,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
auto rs = static_cast<PCB_RENDER_SETTINGS*>(aView->GetPainter()->GetSettings());
auto color = rs->GetColor( NULL, LAYER_RATSNEST );
int highlightedNet = rs->GetHighlightNetCode();
std::set<int> highlightedNets = rs->GetHighlightNetCodes();
gal->SetStrokeColor( color.Brightened(0.5) );
@ -116,10 +116,10 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
continue;
// Draw the "static" ratsnest
if( i != highlightedNet )
gal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
else
if( highlightedNets.count( i ) )
gal->SetStrokeColor( color.Brightened(0.8) );
else
gal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
for( const auto& edge : net->GetUnconnected() )
{

View File

@ -230,7 +230,8 @@ void TOOL_BASE::highlightNet( bool aEnabled, int aNetcode )
{
// If the user has previously set the current net to be highlighted,
// we assume they want to keep it highlighted after routing
m_startHighlight = ( rs->IsHighlightEnabled() && rs->GetHighlightNetCode() == aNetcode );
m_startHighlight =
( rs->IsHighlightEnabled() && rs->GetHighlightNetCodes().count( aNetcode ) );
rs->SetHighlight( true, aNetcode );
}

View File

@ -137,7 +137,7 @@ int PCB_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
}
}
enableHighlight = ( net >= 0 && net != settings->GetHighlightNetCode() );
enableHighlight = ( net >= 0 && !settings->GetHighlightNetCodes().count( net ) );
}
// If we didn't get a net to highlight from the selection, use the cursor
@ -175,13 +175,13 @@ int PCB_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
}
// Toggle highlight when the same net was picked
if( net > 0 && net == settings->GetHighlightNetCode() )
if( net > 0 && settings->GetHighlightNetCodes().count( net ) )
enableHighlight = !settings->IsHighlightEnabled();
if( enableHighlight != settings->IsHighlightEnabled()
|| net != settings->GetHighlightNetCode() )
|| !settings->GetHighlightNetCodes().count( net ) )
{
m_lastNetcode = settings->GetHighlightNetCode();
m_lastNetcode = *settings->GetHighlightNetCodes().begin();
settings->SetHighlight( enableHighlight, net );
m_toolMgr->GetView()->UpdateAllLayersColor();
}
@ -220,13 +220,13 @@ int PCB_INSPECTION_TOOL::HighlightNet( const TOOL_EVENT& aEvent )
if( netcode > 0 )
{
m_lastNetcode = settings->GetHighlightNetCode();
m_lastNetcode = *settings->GetHighlightNetCodes().begin();
settings->SetHighlight( true, netcode );
m_toolMgr->GetView()->UpdateAllLayersColor();
}
else if( aEvent.IsAction( &PCB_ACTIONS::toggleLastNetHighlight ) )
{
int temp = settings->GetHighlightNetCode();
int temp = *settings->GetHighlightNetCodes().begin();
settings->SetHighlight( true, m_lastNetcode );
m_toolMgr->GetView()->UpdateAllLayersColor();
m_lastNetcode = temp;

View File

@ -59,7 +59,8 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
// Get the current default settings for zones
ZONE_SETTINGS zoneInfo = frame.GetZoneSettings();
zoneInfo.m_CurrentZone_Layer = m_params.m_layer;
zoneInfo.m_NetcodeSelection = board.GetHighLightNetCode();
zoneInfo.m_NetcodeSelection =
board.GetHighLightNetCodes().empty() ? -1 : *board.GetHighLightNetCodes().begin();
zoneInfo.SetIsKeepout( m_params.m_keepout );
zoneInfo.m_Zone_45_Only = ( m_params.m_leaderMode == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );