Re-implement sch->pcb cross-probing using net highlighting architecture.

Fixes: lp:1827853
* https://bugs.launchpad.net/kicad/+bug/1827853
This commit is contained in:
Jeff Young 2019-06-26 19:35:56 +01:00
parent e785c140b9
commit fa84babefe
11 changed files with 148 additions and 201 deletions

View File

@ -127,11 +127,15 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
if( strcmp( idcmd, "$REF:" ) == 0 ) if( strcmp( idcmd, "$REF:" ) == 0 )
{ {
FindComponentAndItem( part_ref, true, FIND_REFERENCE, msg ); // Highlighting the reference itself isn't actually that useful, and it's harder to
// see. Highlight the parent and display the message.
FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, msg );
} }
else if( strcmp( idcmd, "$VAL:" ) == 0 ) else if( strcmp( idcmd, "$VAL:" ) == 0 )
{ {
FindComponentAndItem( part_ref, true, FIND_VALUE, msg ); // Highlighting the value itself isn't actually that useful, and it's harder to see.
// Highlight the parent and display the message.
FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, msg );
} }
else if( strcmp( idcmd, "$PAD:" ) == 0 ) else if( strcmp( idcmd, "$PAD:" ) == 0 )
{ {
@ -151,14 +155,6 @@ std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aComp )
// Cross probing to Pcbnew if a pin or a component is found // Cross probing to Pcbnew if a pin or a component is found
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case LIB_PIN_T:
wxFAIL_MSG( "What are we doing with LIB_* items here?" );
break;
case LIB_FIELD_T:
wxFAIL_MSG( "What are we doing with LIB_* items here?" );
// fall through to SCH_FIELD_T:
case SCH_FIELD_T: case SCH_FIELD_T:
if( aComp ) if( aComp )
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) ); return StrPrintf( "$PART: \"%s\"", TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) );

View File

@ -190,13 +190,21 @@ void SCH_VIEW::HideWorksheet()
void SCH_VIEW::HighlightItem( EDA_ITEM *aItem, LIB_PIN* aPin ) void SCH_VIEW::HighlightItem( EDA_ITEM *aItem, LIB_PIN* aPin )
{ {
if( !aItem ) if( aItem && aItem->Type() == SCH_COMPONENT_T && aPin )
{
static_cast<SCH_COMPONENT*>( aItem )->HighlightPin( aPin );
}
else if( aItem )
{
aItem->SetFlags( HIGHLIGHTED );
}
else
{ {
for( auto item : *m_allItems ) for( auto item : *m_allItems )
{ {
// Not all view items can be highlighted, only EDA_ITEMs // Not all view items can be highlighted, only EDA_ITEMs
// So clear flag of only EDA_ITEMs. // So clear flag of only EDA_ITEMs.
auto eitem = dynamic_cast<EDA_ITEM *>( item ); EDA_ITEM* eitem = dynamic_cast<EDA_ITEM*>( item );
if( eitem ) if( eitem )
{ {
@ -210,15 +218,6 @@ void SCH_VIEW::HighlightItem( EDA_ITEM *aItem, LIB_PIN* aPin )
} }
} }
} }
else
{
if( ( aItem->Type() == SCH_COMPONENT_T ) && aPin )
{
static_cast<SCH_COMPONENT*>( aItem )->HighlightPin( aPin );
}
else
aItem->SetFlags( HIGHLIGHTED );
}
// ugly but I guess OK for the moment... // ugly but I guess OK for the moment...
UpdateAllItems( ALL ); UpdateAllItems( ALL );

View File

@ -132,15 +132,17 @@ public:
/** /**
* Function SetHighlight * Function SetHighlight
* Turns on/off highlighting - it may be done for the active layer or the specified net. * Turns on/off highlighting - it may be done for the active layer, the specified net, or
* items with their HIGHLIGHTED flags set.
* @param aEnabled tells if highlighting should be enabled. * @param aEnabled tells if highlighting should be enabled.
* @param aNetcode is optional and if specified, turns on higlighting only for the net with * @param aNetcode is optional and if specified, turns on higlighting only for the net with
* number given as the parameter. * number given as the parameter.
*/ */
inline void SetHighlight( bool aEnabled, int aNetcode = -1 ) inline void SetHighlight( bool aEnabled, int aNetcode = -1, bool aHighlightItems = false )
{ {
m_highlightEnabled = aEnabled; m_highlightEnabled = aEnabled;
m_highlightNetcode = aEnabled ? aNetcode : -1; m_highlightNetcode = aEnabled ? aNetcode : -1;
m_highlightItems = aEnabled ? aHighlightItems : false;
} }
/** /**
@ -282,6 +284,7 @@ protected:
int m_highlightNetcode; ///< Net number that is displayed in highlight int m_highlightNetcode; ///< Net number that is displayed in highlight
///< -1 means that there is no specific net, and whole active ///< -1 means that there is no specific net, and whole active
///< layer is highlighted ///< layer is highlighted
bool m_highlightItems; ///< Highlight items with their HIGHLIGHT flags set
float m_highlightFactor; ///< Factor used for computing hightlight color float m_highlightFactor; ///< Factor used for computing hightlight color
float m_selectFactor; ///< Specifies how color of selected items is changed float m_selectFactor; ///< Specifies how color of selected items is changed

View File

@ -377,10 +377,10 @@ public:
const wxPoint& GetGridOrigin() const { return m_designSettings.m_GridOrigin; } const wxPoint& GetGridOrigin() const { return m_designSettings.m_GridOrigin; }
/** /**
* Function ResetHighLight * Function ResetNetHighLight
* Reset all high light data to the init state * Reset all high light data to the init state
*/ */
void ResetHighLight() void ResetNetHighLight()
{ {
m_highLight.Clear(); m_highLight.Clear();
m_highLightPrevious.Clear(); m_highLightPrevious.Clear();

View File

@ -73,10 +73,13 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
wxString modName; wxString modName;
char* idcmd; char* idcmd;
char* text; char* text;
int netcode = -1;
MODULE* module = NULL; MODULE* module = NULL;
D_PAD* pad = NULL; D_PAD* pad = NULL;
BOARD* pcb = GetBoard(); BOARD* pcb = GetBoard();
wxPoint pos;
KIGFX::VIEW* view = m_toolManager->GetView();
KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
strncpy( line, cmdline, sizeof(line) - 1 ); strncpy( line, cmdline, sizeof(line) - 1 );
line[sizeof(line) - 1] = 0; line[sizeof(line) - 1] = 0;
@ -89,125 +92,22 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
if( strcmp( idcmd, "$NET:" ) == 0 ) if( strcmp( idcmd, "$NET:" ) == 0 )
{ {
if( IsCurrentTool( PCB_ACTIONS::highlightNetTool ) ) wxString net_name = FROM_UTF8( text );
NETINFO_ITEM* netinfo = pcb->FindNet( net_name );
if( netinfo )
{ {
wxString net_name = FROM_UTF8( text ); netcode = netinfo->GetNet();
NETINFO_ITEM* netinfo = pcb->FindNet( net_name );
int netcode = -1;
if( netinfo ) MSG_PANEL_ITEMS items;
netcode = netinfo->GetNet(); netinfo->GetMsgPanelInfo( GetUserUnits(), items );
SetMsgPanel( items );
if( netcode > 0 )
{
pcb->SetHighLightNet( netcode );
if( netinfo )
{
MSG_PANEL_ITEMS items;
netinfo->GetMsgPanelInfo( GetUserUnits(), items );
SetMsgPanel( items );
}
}
auto view = m_toolManager->GetView();
auto rs = view->GetPainter()->GetSettings();
rs->SetHighlight( ( netcode >= 0 ), netcode );
view->UpdateAllLayersColor();
BOX2I bbox;
bool first = true;
auto merge_area = [netcode, &bbox, &first]( BOARD_CONNECTED_ITEM* aItem )
{
if( aItem->GetNetCode() == netcode )
{
if( first )
{
bbox = aItem->GetBoundingBox();
first = false;
}
else
{
bbox.Merge( aItem->GetBoundingBox() );
}
}
};
for( auto zone : pcb->Zones() )
merge_area( zone );
for( auto track : pcb->Tracks() )
merge_area( track );
for( auto mod : pcb->Modules() )
for ( auto mod_pad : mod->Pads() )
merge_area( mod_pad );
if( netcode > 0 && bbox.GetWidth() > 0 && bbox.GetHeight() > 0 )
{
auto bbSize = bbox.Inflate( bbox.GetWidth() * 0.2f ).GetSize();
auto screenSize = view->ToWorld( GetCanvas()->GetClientSize(), false );
double ratio = std::max( fabs( bbSize.x / screenSize.x ),
fabs( bbSize.y / screenSize.y ) );
double scale = view->GetScale() / ratio;
view->SetScale( scale );
view->SetCenter( bbox.Centre() );
}
GetCanvas()->Refresh();
} }
return;
}
else if( strcmp( idcmd, "$CLEAR" ) == 0 )
{
auto view = m_toolManager->GetView();
auto rs = view->GetPainter()->GetSettings();
rs->SetHighlight( false );
view->UpdateAllLayersColor();
pcb->ResetHighLight();
SetMsgPanel( pcb );
GetCanvas()->Refresh();
}
if( text == NULL )
return;
if( strcmp( idcmd, "$PART:" ) == 0 )
{
modName = FROM_UTF8( text );
module = pcb->FindModuleByReference( modName );
if( module )
msg.Printf( _( "%s found" ), modName );
else
msg.Printf( _( "%s not found" ), modName );
SetStatusText( msg );
if( module )
pos = module->GetPosition();
}
else if( strcmp( idcmd, "$SHEET:" ) == 0 )
{
msg.Printf( _( "Selecting all from sheet \"%s\"" ), FROM_UTF8( text ) );
wxString sheetStamp( FROM_UTF8( text ) );
SetStatusText( msg );
GetToolManager()->RunAction( PCB_ACTIONS::selectOnSheetFromEeschema, true,
static_cast<void*>( &sheetStamp ) );
return;
} }
else if( strcmp( idcmd, "$PIN:" ) == 0 ) else if( strcmp( idcmd, "$PIN:" ) == 0 )
{ {
wxString pinName; wxString pinName = FROM_UTF8( text );
int netcode = -1;
pinName = FROM_UTF8( text );
text = strtok( NULL, " \n\r" ); text = strtok( NULL, " \n\r" );
@ -222,24 +122,8 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
pad = module->FindPadByName( pinName ); pad = module->FindPadByName( pinName );
if( pad ) if( pad )
{
netcode = pad->GetNetCode(); netcode = pad->GetNetCode();
// put cursor on the pad:
pos = pad->GetPosition();
}
if( netcode > 0 ) // highlight the pad net
{
pcb->HighLightON();
pcb->SetHighLightNet( netcode );
}
else
{
pcb->HighLightOFF();
pcb->SetHighLightNet( -1 );
}
if( module == NULL ) if( module == NULL )
msg.Printf( _( "%s not found" ), modName ); msg.Printf( _( "%s not found" ), modName );
else if( pad == NULL ) else if( pad == NULL )
@ -249,12 +133,108 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
SetStatusText( msg ); SetStatusText( msg );
} }
else if( strcmp( idcmd, "$PART:" ) == 0 )
if( module ) // if found, center the module on screen, and redraw the screen.
{ {
GetToolManager()->RunAction( PCB_ACTIONS::crossProbeSchToPcb, true, pcb->ResetNetHighLight();
pad ? (BOARD_ITEM*) pad : (BOARD_ITEM*) module );
modName = FROM_UTF8( text );
module = pcb->FindModuleByReference( modName );
if( module )
msg.Printf( _( "%s found" ), modName );
else
msg.Printf( _( "%s not found" ), modName );
SetStatusText( msg );
} }
else if( strcmp( idcmd, "$SHEET:" ) == 0 )
{
msg.Printf( _( "Selecting all from sheet \"%s\"" ), FROM_UTF8( text ) );
wxString sheetStamp( FROM_UTF8( text ) );
SetStatusText( msg );
GetToolManager()->RunAction( PCB_ACTIONS::selectOnSheetFromEeschema, true,
static_cast<void*>( &sheetStamp ) );
return;
}
else if( strcmp( idcmd, "$CLEAR" ) == 0 )
{
renderSettings->SetHighlight( false );
view->UpdateAllLayersColor();
pcb->ResetNetHighLight();
SetMsgPanel( pcb );
GetCanvas()->Refresh();
return;
}
if( module )
{
renderSettings->SetHighlight( true, -1, true );
for( MODULE* mod : pcb->Modules() )
{
mod->ClearHighlighted();
mod->RunOnChildren( []( BOARD_ITEM* child ) { child->ClearHighlighted(); } );
}
module->SetHighlighted();
module->RunOnChildren( []( BOARD_ITEM* child ) { child->SetHighlighted(); } );
view->SetCenter( VECTOR2D( module->GetPosition() ) );
}
else if( netcode > 0 )
{
renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
pcb->SetHighLightNet( netcode );
BOX2I bbox;
auto merge_area = [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
{
if( aItem->GetNetCode() == netcode )
{
if( bbox.GetWidth() == 0 )
bbox = aItem->GetBoundingBox();
else
bbox.Merge( aItem->GetBoundingBox() );
}
};
for( auto zone : pcb->Zones() )
merge_area( zone );
for( auto track : pcb->Tracks() )
merge_area( track );
for( auto mod : pcb->Modules() )
for ( auto mod_pad : mod->Pads() )
merge_area( mod_pad );
if( bbox.GetWidth() > 0 && bbox.GetHeight() > 0 )
{
auto bbSize = bbox.Inflate( bbox.GetWidth() * 0.2f ).GetSize();
auto screenSize = view->ToWorld( GetCanvas()->GetClientSize(), false );
double ratio = std::max( fabs( bbSize.x / screenSize.x ),
fabs( bbSize.y / screenSize.y ) );
double scale = view->GetScale() / ratio;
view->SetScale( scale );
view->SetCenter( bbox.Centre() );
}
}
else
{
renderSettings->SetHighlight( false );
}
view->UpdateAllLayersColor();
// Ensure the display is refreshed, because in some installs the refresh is done only
// when the gal canvas has the focus, and that is not the case when crossprobing from
// Eeschema:
GetCanvas()->Refresh();
} }

View File

@ -73,7 +73,7 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal )
GetScreen()->InitDataPoints( GetPageSizeIU() ); GetScreen()->InitDataPoints( GetPageSizeIU() );
GetBoard()->ResetHighLight(); GetBoard()->ResetNetHighLight();
// Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled) // Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled)
GetBoard()->SetEnabledLayers( LSET().set() ); GetBoard()->SetEnabledLayers( LSET().set() );

View File

@ -241,6 +241,14 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer
return m_layerColorsSel[aLayer]; return m_layerColorsSel[aLayer];
} }
if( m_highlightEnabled && m_highlightItems )
{
if( item->IsHighlighted() )
return m_layerColorsHi[aLayer];
else
return m_layerColorsDark[aLayer];
}
// Try to obtain the netcode for the item // Try to obtain the netcode for the item
if( const BOARD_CONNECTED_ITEM* conItem = dyn_cast<const BOARD_CONNECTED_ITEM*> ( item ) ) if( const BOARD_CONNECTED_ITEM* conItem = dyn_cast<const BOARD_CONNECTED_ITEM*> ( item ) )
netCode = conItem->GetNetCode(); netCode = conItem->GetNetCode();

View File

@ -560,9 +560,6 @@ TOOL_ACTION PCB_ACTIONS::drillOrigin( "pcbnew.EditorControl.drillOrigin",
_( "Drill and Place Offset" ), _( "Place origin point for drill and place files" ), _( "Drill and Place Offset" ), _( "Place origin point for drill and place files" ),
pcb_offset_xpm ); pcb_offset_xpm );
TOOL_ACTION PCB_ACTIONS::crossProbeSchToPcb( "pcbnew.EditorControl.crossProbSchToPcb",
AS_GLOBAL );
TOOL_ACTION PCB_ACTIONS::toggleLock( "pcbnew.EditorControl.toggleLock", TOOL_ACTION PCB_ACTIONS::toggleLock( "pcbnew.EditorControl.toggleLock",
AS_GLOBAL, AS_GLOBAL,
'L', LEGACY_HK_NAME( "Lock/Unlock Footprint" ), 'L', LEGACY_HK_NAME( "Lock/Unlock Footprint" ),

View File

@ -412,7 +412,6 @@ public:
static TOOL_ACTION highlightNetTool; static TOOL_ACTION highlightNetTool;
static TOOL_ACTION highlightNetSelection; static TOOL_ACTION highlightNetSelection;
static TOOL_ACTION drillOrigin; static TOOL_ACTION drillOrigin;
static TOOL_ACTION crossProbeSchToPcb;
static TOOL_ACTION appendBoard; static TOOL_ACTION appendBoard;
// Ratsnest // Ratsnest

View File

@ -954,37 +954,6 @@ int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
} }
int PCB_EDITOR_CONTROL::CrossProbeSchToPcb( const TOOL_EVENT& aEvent )
{
BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
if( item )
{
m_probingSchToPcb = true;
getView()->SetCenter( VECTOR2D( item->GetPosition() ) );
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
// If it is a pad and the net highlighting tool is enabled, highlight the net
if( item->Type() == PCB_PAD_T && m_frame->IsCurrentTool( PCB_ACTIONS::highlightNetTool ) )
{
int net = static_cast<D_PAD*>( item )->GetNetCode();
m_toolMgr->RunAction( PCB_ACTIONS::highlightNet, false, net );
}
else
// Otherwise simply select the corresponding item
{
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, item );
// Ensure the display is refreshed, because in some installs
// the refresh is done only when the gal canvas has the focus, and
// that is not the case when crossprobing from Eeschema:
m_frame->GetCanvas()->Refresh();
}
}
return 0;
}
void PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame, void PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
BOARD_ITEM* originViewItem, const VECTOR2D& aPosition ) BOARD_ITEM* originViewItem, const VECTOR2D& aPosition )
{ {
@ -1122,7 +1091,7 @@ int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
} }
else else
{ {
board->ResetHighLight(); board->ResetNetHighLight();
frame->SetMsgPanel( board ); frame->SetMsgPanel( board );
frame->SendCrossProbeNetName( "" ); frame->SendCrossProbeNetName( "" );
} }
@ -1164,7 +1133,7 @@ int PCB_EDITOR_CONTROL::ClearHighlight( const TOOL_EVENT& aEvent )
auto board = static_cast<BOARD*>( m_toolMgr->GetModel() ); auto board = static_cast<BOARD*>( m_toolMgr->GetModel() );
KIGFX::RENDER_SETTINGS* render = m_toolMgr->GetView()->GetPainter()->GetSettings(); KIGFX::RENDER_SETTINGS* render = m_toolMgr->GetView()->GetPainter()->GetSettings();
board->ResetHighLight(); board->ResetNetHighLight();
render->SetHighlight( false ); render->SetHighlight( false );
m_toolMgr->GetView()->UpdateAllLayersColor(); m_toolMgr->GetView()->UpdateAllLayersColor();
frame->SetMsgPanel( board ); frame->SetMsgPanel( board );
@ -1430,7 +1399,6 @@ void PCB_EDITOR_CONTROL::setTransitions()
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::SelectedEvent ); Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::SelectedEvent );
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::UnselectedEvent ); Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::UnselectedEvent );
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::ClearedEvent ); Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::ClearedEvent );
Go( &PCB_EDITOR_CONTROL::CrossProbeSchToPcb, PCB_ACTIONS::crossProbeSchToPcb.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::toggleLastNetHighlight.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::toggleLastNetHighlight.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ClearHighlight, PCB_ACTIONS::clearHighlight.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::ClearHighlight, PCB_ACTIONS::clearHighlight.MakeEvent() );

View File

@ -108,9 +108,6 @@ public:
///> Notifies eeschema about the selected item. ///> Notifies eeschema about the selected item.
int CrossProbePcbToSch( const TOOL_EVENT& aEvent ); int CrossProbePcbToSch( const TOOL_EVENT& aEvent );
///> Reacts to selection change in eeschema.
int CrossProbeSchToPcb( const TOOL_EVENT& aEvent );
///> Runs the drill origin tool for setting the origin for drill and pick-and-place files. ///> Runs the drill origin tool for setting the origin for drill and pick-and-place files.
int DrillOrigin( const TOOL_EVENT& aEvent ); int DrillOrigin( const TOOL_EVENT& aEvent );