diff --git a/common/netclass.cpp b/common/netclass.cpp index fa2f419ae4..1630049a9e 100644 --- a/common/netclass.cpp +++ b/common/netclass.cpp @@ -50,7 +50,8 @@ const int DEFAULT_DIFF_PAIR_VIAGAP = Millimeter2iu( 0.25 ); NETCLASS::NETCLASS( const wxString& aName ) : - m_Name( aName ) + m_Name( aName ), + m_PcbColor( KIGFX::COLOR4D::UNSPECIFIED ) { // Default settings SetClearance( DEFAULT_CLEARANCE ); @@ -78,6 +79,7 @@ void NETCLASS::SetParams( const NETCLASS& aDefaults ) SetDiffPairWidth( aDefaults.GetDiffPairWidth() ); SetDiffPairGap( aDefaults.GetDiffPairGap() ); SetDiffPairViaGap( aDefaults.GetDiffPairViaGap() ); + SetPcbColor( KIGFX::COLOR4D::UNSPECIFIED ); } diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp index abb51234d0..e9effd861a 100644 --- a/common/project/net_settings.cpp +++ b/common/project/net_settings.cpp @@ -64,6 +64,9 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : { "diff_pair_via_gap", Iu2Millimeter( netclass->GetDiffPairViaGap() ) } }; + if( netclass->GetPcbColor() != KIGFX::COLOR4D::UNSPECIFIED ) + netJson["pcb_color"] = netclass->GetPcbColor(); + if( idx > 0 ) { nlohmann::json membersJson = nlohmann::json::array(); @@ -135,6 +138,9 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : netclass->Add( net.value().get() ); } + if( entry.contains( "pcb_color" ) && entry["pcb_color"].is_string() ) + netclass->SetPcbColor( entry["pcb_color"].get() ); + if( netclass != defaultClass ) m_NetClasses.Add( netclass ); @@ -145,6 +151,34 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : ResolveNetClassAssignments(); }, {} ) ); + + m_params.emplace_back( new PARAM_LAMBDA( "net_colors", + [&]() -> nlohmann::json + { + nlohmann::json ret = {}; + + for( const auto& pair : m_PcbNetColors ) + { + std::string key( pair.first.ToUTF8() ); + ret[key] = pair.second; + } + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( !aJson.is_object() ) + return; + + m_PcbNetColors.clear(); + + for( const auto& pair : aJson.items() ) + { + wxString key( pair.key().c_str(), wxConvUTF8 ); + m_PcbNetColors[key] = pair.value().get(); + } + }, + {} ) ); } @@ -412,4 +446,4 @@ void NET_SETTINGS::ResolveNetClassAssignments() for( wxString& member : members ) m_NetClassAssignments[ prefix + member ] = ii.second; } -} \ No newline at end of file +} diff --git a/include/netclass.h b/include/netclass.h index 8874e34ddf..7b57b42251 100644 --- a/include/netclass.h +++ b/include/netclass.h @@ -36,6 +36,7 @@ #include #include #include +#include class LINE_READER; @@ -75,6 +76,8 @@ protected: int m_diffPairGap; int m_diffPairViaGap; + KIGFX::COLOR4D m_PcbColor; ///< Optional color override for this netclass (PCB context) + public: static const char Default[]; ///< the name of the default NETCLASS @@ -193,6 +196,9 @@ public: int GetDiffPairViaGap() const { return m_diffPairViaGap; } void SetDiffPairViaGap( int aSize ) { m_diffPairViaGap = aSize; } + KIGFX::COLOR4D GetPcbColor() const { return m_PcbColor; } + void SetPcbColor( const KIGFX::COLOR4D& aColor ) { m_PcbColor = aColor; } + /** * Function SetParams * will set all the parameters by copying them from \a defaults. diff --git a/include/project/net_settings.h b/include/project/net_settings.h index 0244ac0726..e3a3f393aa 100644 --- a/include/project/net_settings.h +++ b/include/project/net_settings.h @@ -42,6 +42,14 @@ public: // (buses) and atomic net names (including individual bus members). std::map m_NetClassAssignments; + /** + * A map of fully-qualified net names to colors used in the board context. + * Since these color overrides are for the board, buses are not included here. + * Only nets that the user has assigned custom colors to will be in this list. + * Nets that no longer exist will be deleted during a netlist read in PcbNew. + */ + std::map m_PcbNetColors; + public: /** * Parses a bus vector (e.g. A[7..0]) into name, begin, and end. diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 566ef46833..6a2fd72fff 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS() m_sketchGraphics = false; m_sketchText = false; m_selectionCandidateColor = COLOR4D( 0.0, 1.0, 0.0, 0.75 ); + m_netColorMode = NET_COLOR_MODE::RATSNEST; // By default everything should be displayed as filled for( unsigned int i = 0; i < arrayDim( m_sketchMode ); ++i ) @@ -216,10 +218,25 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption } +void PCB_RENDER_SETTINGS::LoadNetSettings( const NET_SETTINGS& aSettings ) +{ + m_netColors = aSettings.m_PcbNetColors; + + m_netclassColors.clear(); + + for( const auto& pair : aSettings.m_NetClasses ) + { + if( pair.second->GetPcbColor() != COLOR4D::UNSPECIFIED ) + m_netclassColors[pair.first] = pair.second->GetPcbColor(); + } +} + + const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const { int netCode = -1; const EDA_ITEM* item = dynamic_cast( aItem ); + const BOARD_CONNECTED_ITEM* conItem = dynamic_cast ( aItem ); if( item ) { @@ -234,13 +251,7 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer aLayer = LAYER_MOD_TEXT_INVISIBLE; if( item->IsSelected() ) - { return m_layerColorsSel[aLayer]; - } - - // Try to obtain the netcode for the item - if( const BOARD_CONNECTED_ITEM* conItem = dyn_cast ( item ) ) - netCode = conItem->GetNetCode(); if( item->Type() == PCB_MARKER_T ) return m_layerColors[aLayer]; @@ -269,6 +280,10 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer } } + // Try to obtain the netcode for the item + if( conItem ) + netCode = conItem->GetNetCode(); + // Single net highlight mode if( m_highlightEnabled && m_highlightNetcodes.count( netCode ) ) return m_layerColorsHi[aLayer]; @@ -282,6 +297,15 @@ const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer if( m_highlightEnabled ) return m_layerColorsDark[aLayer]; + // Apply net color overrides + if( conItem && m_netColorMode == NET_COLOR_MODE::ALL ) + { + if( m_netColors.count( conItem->GetNetname() ) ) + return m_netColors.at( conItem->GetNetname() ); + else if( m_netclassColors.count( conItem->GetNetClassName() ) ) + return m_netclassColors.at( conItem->GetNetClassName() ); + } + // No special modificators enabled return m_layerColors[aLayer]; } diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index b876a45473..e6cf965c6a 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -48,6 +48,7 @@ class TEXTE_MODULE; class DIMENSION; class PCB_TARGET; class MARKER_PCB; +class NET_SETTINGS; namespace KIGFX { @@ -86,6 +87,13 @@ public: DZ_SHOW_OUTLINED }; + enum class NET_COLOR_MODE + { + OFF, ///< Net (and netclass) colors are not shown + RATSNEST, ///< Net/netclass colors are shown on ratsnest lines only + ALL ///< Net/netclass colors are shown on all net copper + }; + PCB_RENDER_SETTINGS(); /** @@ -96,6 +104,12 @@ public: */ void LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOptions, bool aShowPageLimits ); + /** + * Loads net-specific render settings + * @param aSettings is the NET_SETTINGS for the current proejct + */ + void LoadNetSettings( const NET_SETTINGS& aSettings ); + virtual void LoadColors( const COLOR_SETTINGS* aSettings ) override; /// @copydoc RENDER_SETTINGS::GetColor() @@ -166,6 +180,13 @@ public: bool GetDrawIndividualViaLayers() const { return m_drawIndividualViaLayers; } void SetDrawIndividualViaLayers( bool aFlag ) { m_drawIndividualViaLayers = aFlag; } + NET_COLOR_MODE GetNetColorMode() const { return m_netColorMode; } + void SetNetColorMode( NET_COLOR_MODE aMode ) { m_netColorMode = aMode; } + + std::map& GetNetclassColorMap() { return m_netclassColors; } + + std::map& GetNetColorMap() { return m_netColors; } + protected: ///> Flag determining if items on a given layer should be drawn as an outline or a filled item bool m_sketchMode[GAL_LAYER_ID_END]; @@ -210,6 +231,15 @@ protected: ///> Color used for highlighting selection candidates COLOR4D m_selectionCandidateColor; + + ///> How to display nets and netclasses with color overrides + NET_COLOR_MODE m_netColorMode; + + ///> Overrides for specific netclass colors + std::map m_netclassColors; + + ///> Overrides for specific net colors + std::map m_netColors; }; diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 780153a77e..e429af0dec 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -44,11 +44,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -95,6 +97,11 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() pglayout.SetPageLayout( filename ); + KIGFX::PCB_RENDER_SETTINGS* rs = static_cast( + GetCanvas()->GetView()->GetPainter()->GetSettings() ); + + rs->LoadNetSettings( project.NetSettings() ); + PROJECT_LOCAL_SETTINGS& localSettings = Prj().GetLocalSettings(); SELECTION_FILTER_OPTIONS& filterOpts = GetToolManager()->GetTool()->GetFilter(); diff --git a/pcbnew/ratsnest/ratsnest_viewitem.cpp b/pcbnew/ratsnest/ratsnest_viewitem.cpp index d282567754..36f37b26d8 100644 --- a/pcbnew/ratsnest/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest/ratsnest_viewitem.cpp @@ -74,8 +74,12 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const gal->SetIsStroke( true ); gal->SetIsFill( false ); gal->SetLineWidth( 1.0 ); - auto rs = static_cast(aView->GetPainter()->GetSettings()); - auto color = rs->GetColor( NULL, LAYER_RATSNEST ); + auto rs = static_cast( aView->GetPainter()->GetSettings() ); + + COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST ); + COLOR4D color = defaultColor; + + bool colorByNet = rs->GetNetColorMode() != PCB_RENDER_SETTINGS::NET_COLOR_MODE::OFF; std::set highlightedNets = rs->GetHighlightNetCodes(); @@ -117,6 +121,11 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const if( !net ) continue; + if( colorByNet ) + { + // TODO(JE) - RN_NET to net name / netclass name link + } + // Draw the "static" ratsnest if( highlightedNets.count( i ) ) gal->SetStrokeColor( color.Brightened(0.8) );