Fix color handling in the stackup manager panel

Fixes https://gitlab.com/kicad/code/kicad/issues/5671
This commit is contained in:
Ian McInerney 2021-04-09 00:51:30 +01:00
parent 401bc53038
commit 9939af3e27
2 changed files with 65 additions and 47 deletions

View File

@ -87,8 +87,6 @@ PANEL_SETUP_BOARD_STACKUP::PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB
// Calculates a good size for color swatches (icons) in this dialog // Calculates a good size for color swatches (icons) in this dialog
wxClientDC dc( this ); wxClientDC dc( this );
m_colorSwatchesSize = dc.GetTextExtent( "XX" ); m_colorSwatchesSize = dc.GetTextExtent( "XX" );
m_colorComboSize = dc.GetTextExtent( wxString::Format( "XXX %s XXX",
wxGetTranslation( NotSpecifiedPrm() ) ) );
m_colorIconsSize = dc.GetTextExtent( "XXXX" ); m_colorIconsSize = dc.GetTextExtent( "XXXX" );
// Calculates a good size for wxTextCtrl to enter Epsilon R and Loss tan // Calculates a good size for wxTextCtrl to enter Epsilon R and Loss tan
@ -313,10 +311,8 @@ wxColor PANEL_SETUP_BOARD_STACKUP::GetSelectedColor( int aRow ) const
if( idx != GetColorUserDefinedListIdx() ) // a standard color is selected if( idx != GetColorUserDefinedListIdx() ) // a standard color is selected
return GetColorStandardList()[idx].m_Color; return GetColorStandardList()[idx].m_Color;
else if( m_UserColors.count( aRow ) )
return m_UserColors.at( aRow ); return m_rowUiItemsList[aRow].m_UserColor;
else
return wxNullColour;
} }
@ -376,8 +372,6 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
m_impedanceControlled->SetValue( brd_stackup.m_HasDielectricConstrains ); m_impedanceControlled->SetValue( brd_stackup.m_HasDielectricConstrains );
} }
int row = 0;
for( BOARD_STACKUP_ROW_UI_ITEM& ui_row_item : m_rowUiItemsList ) for( BOARD_STACKUP_ROW_UI_ITEM& ui_row_item : m_rowUiItemsList )
{ {
BOARD_STACKUP_ITEM* item = ui_row_item.m_Item; BOARD_STACKUP_ITEM* item = ui_row_item.m_Item;
@ -429,12 +423,15 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
if( item->GetColor().StartsWith( "#" ) ) // User defined color if( item->GetColor().StartsWith( "#" ) ) // User defined color
{ {
wxColour color( item->GetColor() ); wxColour color( item->GetColor() );
m_UserColors[row] = color; ui_row_item.m_UserColor = color;
color_idx = GetColorUserDefinedListIdx(); color_idx = GetColorUserDefinedListIdx();
if( bm_combo ) // Update user color shown in the wxBitmapComboBox if( bm_combo ) // Update user color shown in the wxBitmapComboBox
{ {
bm_combo->SetString( color_idx, color.GetAsString( wxC2S_HTML_SYNTAX ) ); wxString label = wxString::Format( _( "Custom (%s)" ),
color.GetAsString( wxC2S_HTML_SYNTAX ) );
bm_combo->SetString( color_idx, label );
wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y );
LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D(), COLOR4D( color ) ); LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D(), COLOR4D( color ) );
bm_combo->SetItemBitmap( color_idx, layerbmp ); bm_combo->SetItemBitmap( color_idx, layerbmp );
@ -683,13 +680,17 @@ BOARD_STACKUP_ROW_UI_ITEM PANEL_SETUP_BOARD_STACKUP::createRowData( int aRow,
if( item->IsColorEditable() ) if( item->IsColorEditable() )
{ {
int color_idx = 0; int color_idx = 0;
int user_color_idx = GetColorUserDefinedListIdx();
// Always init the user-defined color for a row
ui_row_item.m_UserColor = GetColorStandardList()[user_color_idx].m_Color;
if( item->GetColor().StartsWith( "#" ) ) // User defined color if( item->GetColor().StartsWith( "#" ) ) // User defined color
{ {
wxColour color( item->GetColor() ); wxColour color( item->GetColor() );
m_UserColors[row] = color; ui_row_item.m_UserColor = color;
color_idx = GetColorUserDefinedListIdx(); color_idx = user_color_idx;
} }
else else
{ {
@ -704,8 +705,6 @@ BOARD_STACKUP_ROW_UI_ITEM PANEL_SETUP_BOARD_STACKUP::createRowData( int aRow,
} }
wxBitmapComboBox* bm_combo = createBmComboBox( item, row ); wxBitmapComboBox* bm_combo = createBmComboBox( item, row );
m_colorComboSize.y = bm_combo->GetSize().y;
bm_combo->SetMinSize( m_colorComboSize );
m_fgGridSizer->Add( bm_combo, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 ); m_fgGridSizer->Add( bm_combo, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
bm_combo->SetSelection( color_idx ); bm_combo->SetSelection( color_idx );
ui_row_item.m_ColorCtrl = bm_combo; ui_row_item.m_ColorCtrl = bm_combo;
@ -778,7 +777,6 @@ void PANEL_SETUP_BOARD_STACKUP::rebuildLayerStackPanel()
} }
m_rowUiItemsList.clear(); m_rowUiItemsList.clear();
m_UserColors.clear();
// In order to recreate a clean grid layer list, we have to delete and // In order to recreate a clean grid layer list, we have to delete and
// recreate the sizer m_fgGridSizer (just deleting items in this size is not enough) // recreate the sizer m_fgGridSizer (just deleting items in this size is not enough)
@ -1019,8 +1017,7 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
if( idx == GetColorUserDefinedListIdx() ) if( idx == GetColorUserDefinedListIdx() )
{ {
wxASSERT( m_UserColors.count( row ) ); wxColour color = ui_item.m_UserColor;
wxColour color = m_UserColors[row];
item->SetColor( color.GetAsString( wxC2S_HTML_SYNTAX ) ); item->SetColor( color.GetAsString( wxC2S_HTML_SYNTAX ) );
} }
else else
@ -1147,20 +1144,28 @@ void PANEL_SETUP_BOARD_STACKUP::onColorSelected( wxCommandEvent& event )
if( GetColorStandardListCount()-1 == idx ) // Set user color is the last option in list if( GetColorStandardListCount()-1 == idx ) // Set user color is the last option in list
{ {
COLOR4D defaultColor( GetColorStandardList()[GetColorUserDefinedListIdx()].m_Color ); wxColour userColour = m_rowUiItemsList[row].m_UserColor;
COLOR4D currentColor( COLOR4D currentColor( userColour.IsOk() ? userColour : COLOR4D( 0.5, 0.5, 0.5, 1.0 ) );
m_UserColors.count( row ) ? m_UserColors[row] : COLOR4D( 0.5, 0.5, 0.5, 1.0 ) ); COLOR4D defaultColor( GetColorStandardList()[GetColorUserDefinedListIdx()].m_Color );
DIALOG_COLOR_PICKER dlg( this, currentColor, false, nullptr, defaultColor ); DIALOG_COLOR_PICKER dlg( this, currentColor, false, nullptr, defaultColor );
// Give a time-slice to close the menu before opening the dialog.
// (Only matters on some versions of GTK.)
wxSafeYield();
if( dlg.ShowModal() == wxID_OK ) if( dlg.ShowModal() == wxID_OK )
{ {
wxBitmapComboBox* combo = static_cast<wxBitmapComboBox*>( FindWindowById( item_id ) ); wxBitmapComboBox* combo = static_cast<wxBitmapComboBox*>( FindWindowById( item_id ) );
wxColour color = dlg.GetColor().ToColour(); wxColour color = dlg.GetColor().ToColour();
m_UserColors[row] = color;
combo->SetString( idx, color.GetAsString( wxC2S_HTML_SYNTAX ) ); m_rowUiItemsList[row].m_UserColor = color;
wxString label = wxString::Format( _( "Custom (%s)" ),
color.GetAsString( wxC2S_HTML_SYNTAX ) );
combo->SetString( idx, label );
wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y );
LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ),
@ -1316,6 +1321,8 @@ wxColor PANEL_SETUP_BOARD_STACKUP::getColorIconItem( int aRow )
break; break;
} }
wxASSERT_MSG( color.IsOk(), "Invalid color in PCB stackup" );
return color; return color;
} }
@ -1325,6 +1332,7 @@ void PANEL_SETUP_BOARD_STACKUP::updateIconColor( int aRow )
if( aRow >= 0 ) if( aRow >= 0 )
{ {
wxStaticBitmap* st_bitmap = m_rowUiItemsList[aRow].m_Icon; wxStaticBitmap* st_bitmap = m_rowUiItemsList[aRow].m_Icon;
// explicit depth important under MSW // explicit depth important under MSW
wxBitmap bmp( m_colorIconsSize.x, m_colorIconsSize.y / 2, 28 ); wxBitmap bmp( m_colorIconsSize.x, m_colorIconsSize.y / 2, 28 );
drawBitmap( bmp, getColorIconItem( aRow ) ); drawBitmap( bmp, getColorIconItem( aRow ) );
@ -1348,6 +1356,7 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITE
wxBitmapComboBox* combo = new wxBitmapComboBox( m_scGridWin, ID_ITEM_COLOR + aRow, wxBitmapComboBox* combo = new wxBitmapComboBox( m_scGridWin, ID_ITEM_COLOR + aRow,
wxEmptyString, wxDefaultPosition, wxEmptyString, wxDefaultPosition,
wxDefaultSize, 0, nullptr, wxCB_READONLY ); wxDefaultSize, 0, nullptr, wxCB_READONLY );
// Fills the combo box with choice list + bitmaps // Fills the combo box with choice list + bitmaps
const FAB_LAYER_COLOR* color_list = GetColorStandardList(); const FAB_LAYER_COLOR* color_list = GetColorStandardList();
@ -1366,14 +1375,10 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITE
else // Append the user color, if specified, else add a default user color else // Append the user color, if specified, else add a default user color
{ {
if( aStackupItem && aStackupItem->GetColor().StartsWith( "#" ) ) if( aStackupItem && aStackupItem->GetColor().StartsWith( "#" ) )
{
curr_color = wxColour( aStackupItem->GetColor() ); curr_color = wxColour( aStackupItem->GetColor() );
label = aStackupItem->GetColor();
} label = wxString::Format( _( "Custom (%s)" ),
else curr_color.GetAsString( wxC2S_HTML_SYNTAX ) );
{
label = curr_color.GetAsString( wxC2S_HTML_SYNTAX );
}
} }
wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y );
@ -1382,14 +1387,20 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITE
combo->Append( label, layerbmp ); combo->Append( label, layerbmp );
} }
#ifdef __WXGTK__ // Ensure the size of the widget is enough to show the text and the icon
// Adjust the minimal width. On GTK, the size calculated by wxWidgets is not good // We have to have a selected item when doing this, because otherwise GTK
// bitmaps are ignored // will just choose a random size that might not fit the actual data
combo->Fit(); // (such as in cases where the font size is very large). So we select
int min_width = combo->GetSize().x; // the longest item (which should be the last item), and size it that way.
min_width += m_colorSwatchesSize.x; int sel = combo->GetSelection();
combo->SetMinSize( wxSize( min_width, -1 ) ); combo->SetSelection( combo->GetCount() - 1 );
#endif
combo->SetMinSize( wxSize( -1, -1 ) );
wxSize bestSize = combo->GetBestSize();
bestSize.x = bestSize.x + m_colorSwatchesSize.x;
combo->SetMinSize( bestSize );
combo->SetSelection( sel );
// add the wxBitmapComboBox to wxControl list, to be able to disconnect the event // add the wxBitmapComboBox to wxControl list, to be able to disconnect the event
// on exit // on exit

View File

@ -28,6 +28,7 @@
#include <board.h> #include <board.h>
#include <widgets/unit_binder.h> #include <widgets/unit_binder.h>
#include <wx/gdicmn.h>
#include "panel_board_stackup_base.h" #include "panel_board_stackup_base.h"
#include "class_board_stackup.h" #include "class_board_stackup.h"
@ -63,14 +64,23 @@ struct BOARD_STACKUP_ROW_UI_ITEM
wxControl* m_EpsilonCtrl; // control shown in column 8 wxControl* m_EpsilonCtrl; // control shown in column 8
wxControl* m_LossTgCtrl; // control shown in column 9 wxControl* m_LossTgCtrl; // control shown in column 9
wxColour m_UserColor; // User-specified color (if any)
BOARD_STACKUP_ROW_UI_ITEM( BOARD_STACKUP_ITEM* aItem, int aSubItem = 1 ) : BOARD_STACKUP_ROW_UI_ITEM( BOARD_STACKUP_ITEM* aItem, int aSubItem = 1 ) :
m_Item( aItem ), m_SubItem( aSubItem ), m_Item( aItem ),
m_isEnabled( true ), m_Icon( nullptr ), m_LayerName( nullptr ), m_SubItem( aSubItem ),
m_isEnabled( true ),
m_Icon( nullptr ),
m_LayerName( nullptr ),
m_LayerTypeCtrl( nullptr ), m_LayerTypeCtrl( nullptr ),
m_MaterialCtrl( nullptr ),m_MaterialButt( nullptr ), m_MaterialCtrl( nullptr ),
m_ThicknessCtrl( nullptr ), m_ThicknessLockCtrl( nullptr ), m_MaterialButt( nullptr ),
m_ThicknessCtrl( nullptr ),
m_ThicknessLockCtrl( nullptr ),
m_ColorCtrl( nullptr ), m_ColorCtrl( nullptr ),
m_EpsilonCtrl( nullptr ), m_LossTgCtrl( nullptr ) m_EpsilonCtrl( nullptr ),
m_LossTgCtrl( nullptr ),
m_UserColor( wxNullColour )
{} {}
}; };
@ -110,8 +120,6 @@ public:
// Called by wxWidgets: transfer current settings stored in m_stackup to the board // Called by wxWidgets: transfer current settings stored in m_stackup to the board
bool TransferDataFromWindow() override; bool TransferDataFromWindow() override;
std::map<int, wxColor> m_UserColors; // the list of user colors for each grid row
// other colors are defined colors, and are not stored
private: private:
/** Creates a BOARD_STACKUP_ROW_UI_ITEM relative to the aStackupItem. /** Creates a BOARD_STACKUP_ROW_UI_ITEM relative to the aStackupItem.
* @return a BOARD_STACKUP_ROW_UI_ITEM filled with corresponding widgets * @return a BOARD_STACKUP_ROW_UI_ITEM filled with corresponding widgets
@ -245,7 +253,6 @@ private:
wxSize m_numericFieldsSize; // Best size to enter double values in wxTextCtrl wxSize m_numericFieldsSize; // Best size to enter double values in wxTextCtrl
wxArrayString m_core_prepreg_choice; // Used to display the option list in dialog wxArrayString m_core_prepreg_choice; // Used to display the option list in dialog
wxSize m_colorSwatchesSize; // the size of color swatches in the wxBitmapComboBox. wxSize m_colorSwatchesSize; // the size of color swatches in the wxBitmapComboBox.
wxSize m_colorComboSize; // the size of the wxBitmapComboBox.
wxSize m_colorIconsSize; // the size of color swatches in grid, left column. wxSize m_colorIconsSize; // the size of color swatches in grid, left column.
// The list of controls (wxChoice, wxBitmapComboBox, wxTextCtrl) added to the panel // The list of controls (wxChoice, wxBitmapComboBox, wxTextCtrl) added to the panel