From cf581137d89940d3c9291422e5ebf94c3459aee3 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 4 Nov 2022 12:20:53 +0000 Subject: [PATCH] Handle multiple unitProviders in a WX_GRID. This allows us to provide a more consistent and less buggy presentation of the netclasses grid in both eeschema and pcbnew. Fixes https://gitlab.com/kicad/code/kicad/issues/12826 --- common/dialogs/panel_setup_netclasses.cpp | 197 ++++++++++------------ common/widgets/wx_grid.cpp | 40 +++-- include/dialogs/panel_setup_netclasses.h | 13 +- include/widgets/wx_grid.h | 4 +- 4 files changed, 130 insertions(+), 124 deletions(-) diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index a569699212..b65921ea86 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -37,12 +37,11 @@ #include #include #include -#include #include #include -// PCBNEW columns of netclasses grid +// columns of netclasses grid enum { GRID_NAME = 0, @@ -65,9 +64,6 @@ enum { GRID_END }; -constexpr int EESCHEMA_COL_OFFSET = GRID_FIRST_EESCHEMA - GRID_FIRST_PCBNEW; - - std::vector g_lineStyleIcons; wxArrayString g_lineStyleNames; @@ -102,47 +98,14 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ m_netclassesDirty = true; - m_netclassGrid->SetUnitsProvider( m_frame ); + m_schUnitsProvider = std::make_unique( schIUScale, m_frame->GetUserUnits() ); + m_pcbUnitsProvider = std::make_unique( pcbIUScale, m_frame->GetUserUnits() ); // Prevent Size events from firing before we are ready Freeze(); m_netclassGrid->BeginBatch(); m_assignmentGrid->BeginBatch(); - if( m_isEEschema ) - { - constexpr int ECO = EESCHEMA_COL_OFFSET; - - m_netclassGrid->DeleteCols( GRID_FIRST_PCBNEW, GRID_FIRST_EESCHEMA - GRID_FIRST_PCBNEW ); - m_netclassGrid->SetAutoEvalCols( { GRID_WIREWIDTH - ECO, GRID_BUSWIDTH - ECO } ); - - wxGridCellAttr* attr = new wxGridCellAttr; - attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( aParent ) ); - attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( aParent, m_netclassGrid ) ); - m_netclassGrid->SetColAttr( GRID_SCHEMATIC_COLOR - ECO, attr ); - - attr = new wxGridCellAttr; - attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_lineStyleIcons, g_lineStyleNames ) ); - attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_lineStyleIcons, g_lineStyleNames ) ); - m_netclassGrid->SetColAttr( GRID_LINESTYLE - ECO, attr ); - - m_colorDefaultHelpText->SetFont( KIUI::GetInfoFont( this ).Italic() ); - } - else - { - m_netclassGrid->DeleteCols( GRID_FIRST_EESCHEMA, GRID_END - GRID_FIRST_EESCHEMA ); - m_netclassGrid->SetAutoEvalCols( { GRID_CLEARANCE, - GRID_TRACKSIZE, - GRID_VIASIZE, - GRID_VIADRILL, - GRID_uVIASIZE, - GRID_uVIADRILL, - GRID_DIFF_PAIR_WIDTH, - GRID_DIFF_PAIR_GAP } ); - - m_colorDefaultHelpText->Hide(); - } - m_originalColWidths = new int[ m_netclassGrid->GetNumberCols() ]; // Calculate a min best size to handle longest usual numeric values: int min_best_width = m_netclassGrid->GetTextExtent( "555,555555 mils" ).x; @@ -163,6 +126,58 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_ m_netclassGrid->SetColSize( i, m_originalColWidths[ i ] ); } + for( int i = GRID_FIRST_PCBNEW; i < GRID_END; ++i ) + { + if( i >= GRID_FIRST_EESCHEMA ) + { + m_netclassGrid->SetUnitsProvider( m_schUnitsProvider.get(), i ); + + if( !m_isEEschema ) + { + m_netclassGrid->HideCol( i ); + m_originalColWidths[ i ] = 0; + } + } + else + { + m_netclassGrid->SetUnitsProvider( m_pcbUnitsProvider.get(), i ); + + if( m_isEEschema ) + { + m_netclassGrid->HideCol( i ); + m_originalColWidths[ i ] = 0; + } + } + } + + wxGridCellAttr* attr = new wxGridCellAttr; + attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( aParent ) ); + attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( aParent, m_netclassGrid ) ); + m_netclassGrid->SetColAttr( GRID_SCHEMATIC_COLOR, attr ); + + attr = new wxGridCellAttr; + attr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( g_lineStyleIcons, g_lineStyleNames ) ); + attr->SetEditor( new GRID_CELL_ICON_TEXT_POPUP( g_lineStyleIcons, g_lineStyleNames ) ); + m_netclassGrid->SetColAttr( GRID_LINESTYLE, attr ); + + if( m_isEEschema ) + m_colorDefaultHelpText->SetFont( KIUI::GetInfoFont( this ).Italic() ); + else + m_colorDefaultHelpText->Hide(); + + m_netclassGrid->SetAutoEvalCols( { GRID_WIREWIDTH, + GRID_BUSWIDTH, + + GRID_CLEARANCE, + GRID_TRACKSIZE, + GRID_VIASIZE, + GRID_VIADRILL, + GRID_uVIASIZE, + GRID_uVIADRILL, + GRID_DIFF_PAIR_WIDTH, + GRID_DIFF_PAIR_GAP } ); + + // Be sure the column labels are readable m_netclassGrid->EnsureColLabelsVisible(); @@ -233,6 +248,10 @@ void PANEL_SETUP_NETCLASSES::onUnitsChanged( wxCommandEvent& aEvent ) m_netSettings = tempNetSettings; TransferDataFromWindow(); + + m_schUnitsProvider->SetUserUnits( m_frame->GetUserUnits() ); + m_pcbUnitsProvider->SetUserUnits( m_frame->GetUserUnits() ); + TransferDataToWindow(); m_netSettings = saveNetSettings; @@ -250,35 +269,27 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow() { m_netclassGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() ); - if( m_isEEschema ) - { - constexpr int ECO = EESCHEMA_COL_OFFSET; + m_netclassGrid->SetUnitValue( aRow, GRID_WIREWIDTH, nc->GetWireWidth() ); + m_netclassGrid->SetUnitValue( aRow, GRID_BUSWIDTH, nc->GetBusWidth() ); - m_netclassGrid->SetUnitValue( aRow, GRID_WIREWIDTH - ECO, nc->GetWireWidth() ); - m_netclassGrid->SetUnitValue( aRow, GRID_BUSWIDTH - ECO, nc->GetBusWidth() ); + wxString colorAsString = nc->GetSchematicColor().ToCSSString(); + m_netclassGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR, colorAsString ); - wxString colorAsString = nc->GetSchematicColor().ToCSSString(); - m_netclassGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR - ECO, colorAsString ); + int lineStyleIdx = std::max( 0, nc->GetLineStyle() ); - int lineStyleIdx = std::max( 0, nc->GetLineStyle() ); + if( lineStyleIdx >= (int) g_lineStyleNames.size() ) + lineStyleIdx = 0; - if( lineStyleIdx >= (int) g_lineStyleNames.size() ) - lineStyleIdx = 0; + m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE, g_lineStyleNames[ lineStyleIdx ] ); - m_netclassGrid->SetCellValue( aRow, GRID_LINESTYLE - EESCHEMA_COL_OFFSET, - g_lineStyleNames[ lineStyleIdx ] ); - } - else - { - m_netclassGrid->SetUnitValue( aRow, GRID_CLEARANCE, nc->GetClearance() ); - m_netclassGrid->SetUnitValue( aRow, GRID_TRACKSIZE, nc->GetTrackWidth() ); - m_netclassGrid->SetUnitValue( aRow, GRID_VIASIZE, nc->GetViaDiameter() ); - m_netclassGrid->SetUnitValue( aRow, GRID_VIADRILL, nc->GetViaDrill() ); - m_netclassGrid->SetUnitValue( aRow, GRID_uVIASIZE, nc->GetuViaDiameter() ); - m_netclassGrid->SetUnitValue( aRow, GRID_uVIADRILL, nc->GetuViaDrill() ); - m_netclassGrid->SetUnitValue( aRow, GRID_DIFF_PAIR_WIDTH, nc->GetDiffPairWidth() ); - m_netclassGrid->SetUnitValue( aRow, GRID_DIFF_PAIR_GAP, nc->GetDiffPairGap() ); - } + m_netclassGrid->SetUnitValue( aRow, GRID_CLEARANCE, nc->GetClearance() ); + m_netclassGrid->SetUnitValue( aRow, GRID_TRACKSIZE, nc->GetTrackWidth() ); + m_netclassGrid->SetUnitValue( aRow, GRID_VIASIZE, nc->GetViaDiameter() ); + m_netclassGrid->SetUnitValue( aRow, GRID_VIADRILL, nc->GetViaDrill() ); + m_netclassGrid->SetUnitValue( aRow, GRID_uVIASIZE, nc->GetuViaDiameter() ); + m_netclassGrid->SetUnitValue( aRow, GRID_uVIADRILL, nc->GetuViaDrill() ); + m_netclassGrid->SetUnitValue( aRow, GRID_DIFF_PAIR_WIDTH, nc->GetDiffPairWidth() ); + m_netclassGrid->SetUnitValue( aRow, GRID_DIFF_PAIR_GAP, nc->GetDiffPairGap() ); }; m_netclassGrid->ClearRows(); @@ -348,31 +359,24 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow() { nc->SetName( m_netclassGrid->GetCellValue( aRow, GRID_NAME ) ); - if( m_isEEschema ) - { - constexpr int ECO = EESCHEMA_COL_OFFSET; + nc->SetWireWidth( m_netclassGrid->GetUnitValue( aRow, GRID_WIREWIDTH ) ); + nc->SetBusWidth( m_netclassGrid->GetUnitValue( aRow, GRID_BUSWIDTH ) ); - nc->SetWireWidth( m_netclassGrid->GetUnitValue( aRow, GRID_WIREWIDTH - ECO ) ); - nc->SetBusWidth( m_netclassGrid->GetUnitValue( aRow, GRID_BUSWIDTH - ECO ) ); + wxString color = m_netclassGrid->GetCellValue( aRow, GRID_SCHEMATIC_COLOR ); + nc->SetSchematicColor( wxColour( color ) ); - wxString color = m_netclassGrid->GetCellValue( aRow, GRID_SCHEMATIC_COLOR - ECO ); - nc->SetSchematicColor( wxColour( color ) ); + wxString lineStyle = m_netclassGrid->GetCellValue( aRow, GRID_LINESTYLE ); + nc->SetLineStyle( g_lineStyleNames.Index( lineStyle ) ); + wxASSERT_MSG( nc->GetLineStyle() >= 0, "Line style name not found." ); - wxString lineStyle = m_netclassGrid->GetCellValue( aRow, GRID_LINESTYLE - ECO ); - nc->SetLineStyle( g_lineStyleNames.Index( lineStyle ) ); - wxASSERT_MSG( nc->GetLineStyle() >= 0, "Line style name not found." ); - } - else - { - nc->SetClearance( m_netclassGrid->GetUnitValue( aRow, GRID_CLEARANCE ) ); - nc->SetTrackWidth( m_netclassGrid->GetUnitValue( aRow, GRID_TRACKSIZE ) ); - nc->SetViaDiameter( m_netclassGrid->GetUnitValue( aRow, GRID_VIASIZE ) ); - nc->SetViaDrill( m_netclassGrid->GetUnitValue( aRow, GRID_VIADRILL ) ); - nc->SetuViaDiameter( m_netclassGrid->GetUnitValue( aRow, GRID_uVIASIZE ) ); - nc->SetuViaDrill( m_netclassGrid->GetUnitValue( aRow, GRID_uVIADRILL ) ); - nc->SetDiffPairWidth( m_netclassGrid->GetUnitValue( aRow, GRID_DIFF_PAIR_WIDTH ) ); - nc->SetDiffPairGap( m_netclassGrid->GetUnitValue( aRow, GRID_DIFF_PAIR_GAP ) ); - } + nc->SetClearance( m_netclassGrid->GetUnitValue( aRow, GRID_CLEARANCE ) ); + nc->SetTrackWidth( m_netclassGrid->GetUnitValue( aRow, GRID_TRACKSIZE ) ); + nc->SetViaDiameter( m_netclassGrid->GetUnitValue( aRow, GRID_VIASIZE ) ); + nc->SetViaDrill( m_netclassGrid->GetUnitValue( aRow, GRID_VIADRILL ) ); + nc->SetuViaDiameter( m_netclassGrid->GetUnitValue( aRow, GRID_uVIASIZE ) ); + nc->SetuViaDrill( m_netclassGrid->GetUnitValue( aRow, GRID_uVIADRILL ) ); + nc->SetDiffPairWidth( m_netclassGrid->GetUnitValue( aRow, GRID_DIFF_PAIR_WIDTH ) ); + nc->SetDiffPairGap( m_netclassGrid->GetUnitValue( aRow, GRID_DIFF_PAIR_GAP ) ); }; m_netSettings->m_NetClasses.clear(); @@ -484,9 +488,6 @@ void PANEL_SETUP_NETCLASSES::OnNetclassGridMouseEvent( wxMouseEvent& aEvent ) wxString tip; - if( m_isEEschema && col > GRID_NAME ) - col += EESCHEMA_COL_OFFSET; - switch( col ) { case GRID_CLEARANCE: tip = _( "Minimum copper clearance" ); break; @@ -525,22 +526,8 @@ void PANEL_SETUP_NETCLASSES::OnAddNetclassClick( wxCommandEvent& event ) m_netclassGrid->AppendRows(); // Copy values of the default class: - if( m_isEEschema ) - { - for( int col = GRID_FIRST_EESCHEMA; col < GRID_END; col++ ) - { - wxString defaultValue = m_netclassGrid->GetCellValue( 0, col - EESCHEMA_COL_OFFSET ); - m_netclassGrid->SetCellValue( row, col - EESCHEMA_COL_OFFSET, defaultValue ); - } - } - else - { - for( int col = GRID_FIRST_PCBNEW; col < GRID_FIRST_EESCHEMA; col++ ) - { - wxString defaultValue = m_netclassGrid->GetCellValue( 0, col ); - m_netclassGrid->SetCellValue( row, col, defaultValue ); - } - } + for( int col = 1; col < m_netclassGrid->GetNumberCols(); col++ ) + m_netclassGrid->SetCellValue( row, col, m_netclassGrid->GetCellValue( 0, col ) ); m_netclassGrid->MakeCellVisible( row, 0 ); m_netclassGrid->SetGridCursor( row, 0 ); diff --git a/common/widgets/wx_grid.cpp b/common/widgets/wx_grid.cpp index 91ac964bb6..bf862d8f51 100644 --- a/common/widgets/wx_grid.cpp +++ b/common/widgets/wx_grid.cpp @@ -34,8 +34,7 @@ WX_GRID::WX_GRID( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxGrid( parent, id, pos, size, style, name ), - m_weOwnTable( false ), - m_unitsProvider( nullptr ) + m_weOwnTable( false ) { SetDefaultCellOverflow( false ); @@ -158,20 +157,25 @@ void WX_GRID::onCellEditorHidden( wxGridEvent& aEvent ) { if( alg::contains( m_autoEvalCols, aEvent.GetCol() ) ) { - m_eval->SetDefaultUnits( m_unitsProvider->GetUserUnits() ); + UNITS_PROVIDER* unitsProvider = m_unitsProviders[ aEvent.GetCol() ]; + + if( !unitsProvider ) + unitsProvider = m_unitsProviders.begin()->second; + + m_eval->SetDefaultUnits( unitsProvider->GetUserUnits() ); int row = aEvent.GetRow(); int col = aEvent.GetCol(); CallAfter( - [this, row, col]() + [this, row, col, unitsProvider]() { wxString stringValue = GetCellValue( row, col ); if( m_eval->Process( stringValue ) ) { - int val = m_unitsProvider->ValueFromString( m_eval->Result() ); - wxString evalValue = m_unitsProvider->StringFromValue( val, true ); + int val = unitsProvider->ValueFromString( m_eval->Result() ); + wxString evalValue = unitsProvider->StringFromValue( val, true ); if( stringValue != evalValue ) { @@ -322,32 +326,44 @@ bool WX_GRID::CommitPendingChanges( bool aQuietMode ) } -void WX_GRID::SetUnitsProvider( UNITS_PROVIDER* aProvider ) +void WX_GRID::SetUnitsProvider( UNITS_PROVIDER* aProvider, int aCol ) { - m_unitsProvider = aProvider; - m_eval = std::make_unique( m_unitsProvider->GetUserUnits() ); + m_unitsProviders[ aCol ] = aProvider; + + if( !m_eval ) + m_eval = std::make_unique( aProvider->GetUserUnits() ); } int WX_GRID::GetUnitValue( int aRow, int aCol ) { + UNITS_PROVIDER* unitsProvider = m_unitsProviders[ aCol ]; + + if( !unitsProvider ) + unitsProvider = m_unitsProviders.begin()->second; + wxString stringValue = GetCellValue( aRow, aCol ); if( alg::contains( m_autoEvalCols, aCol ) ) { - m_eval->SetDefaultUnits( m_unitsProvider->GetUserUnits() ); + m_eval->SetDefaultUnits( unitsProvider->GetUserUnits() ); if( m_eval->Process( stringValue ) ) stringValue = m_eval->Result(); } - return m_unitsProvider->ValueFromString( stringValue ); + return unitsProvider->ValueFromString( stringValue ); } void WX_GRID::SetUnitValue( int aRow, int aCol, int aValue ) { - SetCellValue( aRow, aCol, m_unitsProvider->StringFromValue( aValue, true ) ); + UNITS_PROVIDER* unitsProvider = m_unitsProviders[ aCol ]; + + if( !unitsProvider ) + unitsProvider = m_unitsProviders.begin()->second; + + SetCellValue( aRow, aCol, unitsProvider->StringFromValue( aValue, true ) ); } diff --git a/include/dialogs/panel_setup_netclasses.h b/include/dialogs/panel_setup_netclasses.h index 873d599a50..7652af08d8 100644 --- a/include/dialogs/panel_setup_netclasses.h +++ b/include/dialogs/panel_setup_netclasses.h @@ -68,11 +68,14 @@ private: void AdjustAssignmentGridColumns( int aWidth ); private: - EDA_DRAW_FRAME* m_frame; - PAGED_DIALOG* m_parent; - bool m_isEEschema; - std::shared_ptr m_netSettings; - std::set m_netNames; + EDA_DRAW_FRAME* m_frame; + PAGED_DIALOG* m_parent; + bool m_isEEschema; + std::shared_ptr m_netSettings; + std::set m_netNames; + + std::unique_ptr m_schUnitsProvider; + std::unique_ptr m_pcbUnitsProvider; int* m_originalColWidths; bool m_netclassesDirty; // The netclass drop-down menus need rebuilding diff --git a/include/widgets/wx_grid.h b/include/widgets/wx_grid.h index 42e0c1477f..250e22811c 100644 --- a/include/widgets/wx_grid.h +++ b/include/widgets/wx_grid.h @@ -85,7 +85,7 @@ public: * Set a UNITS_PROVIDER to enable use of unit- and eval-based Getters. * @param aProvider */ - void SetUnitsProvider( UNITS_PROVIDER* aProvider ); + void SetUnitsProvider( UNITS_PROVIDER* aProvider, int aCol = 0 ); void SetAutoEvalCols( const std::vector& aCols ) { m_autoEvalCols = aCols; } @@ -156,7 +156,7 @@ protected: protected: bool m_weOwnTable; - UNITS_PROVIDER* m_unitsProvider; + std::map m_unitsProviders; std::unique_ptr m_eval; std::vector m_autoEvalCols;