From f5597238fbb32c309767cb873b952c2abf5592a5 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 22 Aug 2021 11:59:02 -0400 Subject: [PATCH] Properties: add color swatch to layer enum --- common/pg_properties.cpp | 28 ++++++++++++++ include/pg_properties.h | 30 +++++++++++++++ pcbnew/dialogs/pcb_properties_panel.cpp | 50 +++++++++++++------------ 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/common/pg_properties.cpp b/common/pg_properties.cpp index a9b9a12db3..4066f84e7c 100644 --- a/common/pg_properties.cpp +++ b/common/pg_properties.cpp @@ -27,6 +27,7 @@ #include #include #include +#include // reg-ex describing a signed valid value with a unit static const wxChar REGEX_SIGNED_DISTANCE[] = wxT( "([-+]?[0-9]+[\\.?[0-9]*) *(mm|in)*" ); @@ -275,3 +276,30 @@ wxString PGPROPERTY_ANGLE::ValueToString( wxVariant& aVariant, int aArgFlags ) c wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_DOUBLE, wxEmptyString ); return wxString::Format( wxT("%g\u00B0"), aVariant.GetDouble() / m_scale ); } + + +wxSize PGPROPERTY_COLORENUM::OnMeasureImage( int aItem ) const +{ + // TODO(JE) calculate size from window metrics? + return wxSize( 16, 12 ); +} + + +void PGPROPERTY_COLORENUM::OnCustomPaint( wxDC& aDC, const wxRect& aRect, + wxPGPaintData& aPaintData ) +{ + int index = aPaintData.m_choiceItem; + + if( index < 0 ) + index = GetIndex(); + + wxString layer = GetChoices().GetLabel( index ); + wxColour color = GetColor( layer ); + + if( color == wxNullColour ) + return; + + aDC.SetPen( *wxTRANSPARENT_PEN ); + aDC.SetBrush( wxBrush( color ) ); + aDC.DrawRectangle( aRect ); +} diff --git a/include/pg_properties.h b/include/pg_properties.h index 6227361349..e29b7240a3 100644 --- a/include/pg_properties.h +++ b/include/pg_properties.h @@ -109,4 +109,34 @@ protected: double m_scale; }; + +///> A wxEnumProperty that displays a color next to the enum value +class PGPROPERTY_COLORENUM : public wxEnumProperty +{ +public: + PGPROPERTY_COLORENUM( const wxString& aLabel, wxString& aName, const wxPGChoices& aChoices, + int aValue = 0 ) : + wxEnumProperty( aLabel, aName, const_cast( aChoices ), aValue ), + m_colorFunc( []( const wxString& aChoice ) { return wxNullColour; } ) + { + } + + wxSize OnMeasureImage( int aItem = -1 ) const override; + + void OnCustomPaint( wxDC& aDC, const wxRect& aRect, wxPGPaintData& aPaintData ) override; + + void SetColorFunc( std::function aFunc ) + { + m_colorFunc = aFunc; + } + + wxColour GetColor( const wxString& aChoice ) + { + return m_colorFunc( aChoice ); + } + +protected: + std::function m_colorFunc; +}; + #endif /* PG_PROPERTIES_H */ diff --git a/pcbnew/dialogs/pcb_properties_panel.cpp b/pcbnew/dialogs/pcb_properties_panel.cpp index c9fcadf739..447b2b4f7e 100644 --- a/pcbnew/dialogs/pcb_properties_panel.cpp +++ b/pcbnew/dialogs/pcb_properties_panel.cpp @@ -28,6 +28,7 @@ #include #include #include +#include PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_EDIT_FRAME* aFrame ) @@ -50,6 +51,29 @@ void PCB_PROPERTIES_PANEL::UpdateData() wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const { + if( aProperty->TypeHash() == TYPE_HASH( PCB_LAYER_ID ) ) + { + wxASSERT( aProperty->HasChoices() ); + + PGPROPERTY_COLORENUM* ret = new PGPROPERTY_COLORENUM( wxPG_LABEL, wxPG_LABEL, + const_cast( aProperty->Choices() ) ); + + ret->SetColorFunc( + [&]( const wxString& aChoice ) -> wxColour + { + PCB_LAYER_ID l = ENUM_MAP::Instance().ToEnum( aChoice ); + wxASSERT( IsPcbLayer( l ) ); + return m_frame->GetColorSettings()->GetColor( l ).ToColour(); + } ); + + ret->SetLabel( aProperty->Name() ); + ret->SetName( aProperty->Name() ); + ret->Enable( !aProperty->IsReadOnly() ); + ret->SetClientData( const_cast( aProperty ) ); + + return ret; + } + return PGPropertyFactory( aProperty ); } @@ -83,29 +107,9 @@ void PCB_PROPERTIES_PANEL::updateLists( const BOARD* aBoard ) for( LSEQ layerSeq = aBoard->GetEnabledLayers().UIOrder(); layerSeq; ++layerSeq ) layersAll.Add( LSET::Name( *layerSeq ), *layerSeq ); - m_propMgr.GetProperty( TYPE_HASH( BOARD_ITEM ), _( "Layer" ) )->SetChoices( layersAll ); - - - // Regenerate non-copper layers - for( LSEQ layerSeq = LSET( LSET::AllNonCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) - layersNonCu.Add( LSET::Name( *layerSeq ), *layerSeq ); - - m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _( "Layer" ) )->SetChoices( layersNonCu ); - - - // Regenerate copper layers - for( LSEQ layerSeq = LSET( LSET::AllCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) - layersCu.Add( LSET::Name( *layerSeq ), *layerSeq ); - - m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _( "Layer" ) )->SetChoices( layersCu ); - - - // Regenerate non-copper layers - for( LSEQ layerSeq = LSET( LSET::AllNonCuMask() & aBoard->GetEnabledLayers() ).UIOrder(); layerSeq; ++layerSeq ) - layersNonCu.Add( LSET::Name( *layerSeq ), *layerSeq ); - - m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _( "Layer" ) )->SetChoices( layersNonCu ); - + m_propMgr.GetProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ) )->SetChoices( layersAll ); + m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _HKI( "Layer" ) )->SetChoices( layersAll ); + m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) )->SetChoices( layersAll ); // Regenerate nets for( const auto& netinfo : aBoard->GetNetInfo().NetsByNetcode() )