Rework stackup colors a bit to support opacity for 3D viewer.

Fixes https://gitlab.com/kicad/code/kicad/issues/9012
This commit is contained in:
Jeff Young 2021-08-23 19:58:18 +01:00
parent fec34e8dd8
commit 21f2b235ce
4 changed files with 123 additions and 79 deletions

View File

@ -97,13 +97,13 @@ PANEL_SETUP_BOARD_STACKUP::PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB
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
// ("0.000000" + margins) // ("0.0000000" + margins)
m_numericFieldsSize = dc.GetTextExtent( "X.XXXXXX" ); m_numericFieldsSize = dc.GetTextExtent( "X.XXXXXXX" );
m_numericFieldsSize.y = -1; // Use default for the vertical size m_numericFieldsSize.y = -1; // Use default for the vertical size
// Calculates a minimal size for wxTextCtrl to enter a dim with units // Calculates a minimal size for wxTextCtrl to enter a dim with units
// ("000.0000000 mils" + margins) // ("000.0000000 mils" + margins)
m_numericTextCtrlSize = dc.GetTextExtent( "XXX.XXXXXX mils" ); m_numericTextCtrlSize = dc.GetTextExtent( "XXX.XXXXXXX mils" );
m_numericTextCtrlSize.y = -1; // Use default for the vertical size m_numericTextCtrlSize.y = -1; // Use default for the vertical size
// The grid column containing the lock checkbox is kept to a minimal // The grid column containing the lock checkbox is kept to a minimal
@ -412,15 +412,17 @@ void PANEL_SETUP_BOARD_STACKUP::onExportToClipboard( wxCommandEvent& event )
wxColor PANEL_SETUP_BOARD_STACKUP::GetSelectedColor( int aRow ) const wxColor PANEL_SETUP_BOARD_STACKUP::GetSelectedColor( int aRow ) const
{ {
wxBitmapComboBox* choice = dynamic_cast<wxBitmapComboBox*>( m_rowUiItemsList[aRow].m_ColorCtrl ); const BOARD_STACKUP_ROW_UI_ITEM& row = m_rowUiItemsList[aRow];
const BOARD_STACKUP_ITEM* item = row.m_Item;
const wxBitmapComboBox* choice = dynamic_cast<wxBitmapComboBox*>( row.m_ColorCtrl );
wxASSERT( choice ); wxASSERT( choice );
int idx = choice ? choice->GetSelection() : 0; int idx = choice ? choice->GetSelection() : 0;
if( idx != GetColorUserDefinedListIdx() ) // a standard color is selected if( idx != GetColorUserDefinedListIdx() ) // a standard color is selected
return GetColorStandardList()[idx].m_Color; return GetColorStandardList()[idx].GetColor( item->GetType() );
else
return m_rowUiItemsList[aRow].m_UserColor; return m_rowUiItemsList[aRow].m_UserColor;
} }
@ -472,7 +474,8 @@ void PANEL_SETUP_BOARD_STACKUP::updateCopperLayerCount()
void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync ) void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
{ {
const BOARD_STACKUP& brd_stackup = m_brdSettings->GetStackupDescriptor(); const BOARD_STACKUP& brd_stackup = m_brdSettings->GetStackupDescriptor();
const FAB_LAYER_COLOR* color_list = GetColorStandardList();
if( aFullSync ) if( aFullSync )
{ {
@ -526,41 +529,38 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
if( item->IsColorEditable() ) if( item->IsColorEditable() )
{ {
auto bm_combo = dynamic_cast<wxBitmapComboBox*>( ui_row_item.m_ColorCtrl ); auto bm_combo = dynamic_cast<wxBitmapComboBox*>( ui_row_item.m_ColorCtrl );
int color_idx = 0;
if( item->GetColor().StartsWith( "#" ) ) // User defined color if( item->GetColor().StartsWith( "#" ) ) // User defined color
{ {
wxColour color( item->GetColor() ); ui_row_item.m_UserColor = wxColour( item->GetColor() );
ui_row_item.m_UserColor = color;
color_idx = GetColorUserDefinedListIdx();
if( bm_combo ) // Update user color shown in the wxBitmapComboBox if( bm_combo ) // Update user color shown in the wxBitmapComboBox
{ {
wxString label = wxString::Format( _( "Custom (%s)" ), bm_combo->SetString( GetColorUserDefinedListIdx(), item->GetColor() );
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(),
bm_combo->SetItemBitmap( color_idx, layerbmp ); wxColour( item->GetColor() ) );
bm_combo->SetItemBitmap( GetColorUserDefinedListIdx(), layerbmp );
bm_combo->SetSelection( GetColorUserDefinedListIdx() );
} }
} }
else else
{ {
const FAB_LAYER_COLOR* color_list = GetColorStandardList(); if( bm_combo )
for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{ {
if( color_list[ii].m_ColorName == item->GetColor() ) // Note: don't use bm_combo->FindString() because the combo strings are
// translated.
for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{ {
color_idx = ii; if( color_list[ii].GetName() == item->GetColor() )
break; {
bm_combo->SetSelection( ii );
break;
}
} }
} }
} }
if( bm_combo )
bm_combo->SetSelection( color_idx );
} }
if( item->HasEpsilonRValue() ) if( item->HasEpsilonRValue() )
@ -785,33 +785,32 @@ BOARD_STACKUP_ROW_UI_ITEM PANEL_SETUP_BOARD_STACKUP::createRowData( int aRow,
if( item->IsColorEditable() ) if( item->IsColorEditable() )
{ {
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
ui_row_item.m_UserColor = wxColour( item->GetColor() );
else
ui_row_item.m_UserColor = GetDefaultUserColor( item->GetType() );
wxBitmapComboBox* bm_combo = createColorBox( item, row );
m_fgGridSizer->Add( bm_combo, 1, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2 );
if( item->GetColor().StartsWith( "#" ) )
{ {
wxColour color( item->GetColor() ); bm_combo->SetString( GetColorUserDefinedListIdx(), item->GetColor() );
ui_row_item.m_UserColor = color; bm_combo->SetSelection( GetColorUserDefinedListIdx() );
color_idx = user_color_idx;
} }
else else
{ {
// Note: don't use bm_combo->FindString() because the combo strings are translated.
for( int ii = 0; ii < GetColorStandardListCount(); ii++ ) for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{ {
if( color_list[ii].m_ColorName == item->GetColor() ) if( color_list[ii].GetName() == item->GetColor() )
{ {
color_idx = ii; bm_combo->SetSelection( ii );
break; break;
} }
} }
} }
wxBitmapComboBox* bm_combo = createBmComboBox( item, row );
m_fgGridSizer->Add( bm_combo, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
bm_combo->SetSelection( color_idx );
ui_row_item.m_ColorCtrl = bm_combo; ui_row_item.m_ColorCtrl = bm_combo;
} }
else else
@ -1116,7 +1115,7 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
} }
else else
{ {
item->SetColor( color_list[idx].m_ColorName ); item->SetColor( color_list[idx].GetName() );
} }
} }
} }
@ -1240,34 +1239,31 @@ void PANEL_SETUP_BOARD_STACKUP::onColorSelected( wxCommandEvent& event )
int row = item_id - ID_ITEM_COLOR; int row = item_id - ID_ITEM_COLOR;
if( GetColorStandardListCount()-1 == idx ) // Set user color is the last option in list if( idx == GetColorStandardListCount() - 1 ) // Set user color is the last option in list
{ {
wxColour userColour = m_rowUiItemsList[row].m_UserColor; DIALOG_COLOR_PICKER dlg( this, m_rowUiItemsList[row].m_UserColor, true, nullptr,
COLOR4D currentColor( userColour.IsOk() ? userColour : COLOR4D( 0.5, 0.5, 0.5, 1.0 ) ); GetDefaultUserColor( m_rowUiItemsList[row].m_Item->GetType() ) );
COLOR4D defaultColor( GetColorStandardList()[GetColorUserDefinedListIdx()].m_Color );
DIALOG_COLOR_PICKER dlg( this, currentColor, false, nullptr, defaultColor );
#ifdef __WXGTK__
// Give a time-slice to close the menu before opening the dialog. // Give a time-slice to close the menu before opening the dialog.
// (Only matters on some versions of GTK.) // (Only matters on some versions of GTK.)
wxSafeYield(); wxSafeYield();
#endif
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_rowUiItemsList[row].m_UserColor = color; m_rowUiItemsList[row].m_UserColor = color;
wxString label = wxString::Format( _( "Custom (%s)" ), combo->SetString( idx, color.GetAsString( wxC2S_HTML_SYNTAX ) );
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 ), COLOR4D( color ) ); LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), COLOR4D( color ) );
combo->SetItemBitmap( combo->GetCount()-1, layerbmp ); combo->SetItemBitmap( combo->GetCount()-1, layerbmp );
combo->SetSelection( idx );
} }
} }
@ -1447,35 +1443,38 @@ void PANEL_SETUP_BOARD_STACKUP::updateIconColor( int aRow )
} }
wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITEM* aStackupItem, wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createColorBox( BOARD_STACKUP_ITEM* aStackupItem,
int aRow ) int aRow )
{ {
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();
BOARD_STACKUP_ITEM_TYPE itemType = aStackupItem ? aStackupItem->GetType()
: BS_ITEM_TYPE_SILKSCREEN;
for( int ii = 0; ii < GetColorStandardListCount(); ii++ ) for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{ {
const FAB_LAYER_COLOR& item = color_list[ii]; wxColor curr_color;
wxColor curr_color = item.m_Color;
wxString label; wxString label;
// Defined colors have a name, the user color uses the HTML notation ( i.e. #FF0000) // Defined colors have a name, the user color uses the HTML notation ( i.e. #FF0000)
if( GetColorStandardListCount()-1 > (int)combo->GetCount() ) if( ii == GetColorUserDefinedListIdx() )
{
label = wxGetTranslation( item.m_ColorName );
}
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() );
else
curr_color = color_list[ii].GetColor( itemType );
label = wxString::Format( _( "Custom (%s)" ), label = _( curr_color.GetAsString( wxC2S_HTML_SYNTAX ) );
curr_color.GetAsString( wxC2S_HTML_SYNTAX ) ); }
else // Append the user color, if specified, else add a default user color
{
curr_color = color_list[ii].GetColor( itemType );
label = wxGetTranslation( color_list[ii].GetName() );
} }
wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y );
@ -1507,6 +1506,12 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITE
wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP::onColorSelected ), wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP::onColorSelected ),
nullptr, this ); nullptr, this );
combo->Bind( wxEVT_COMBOBOX_DROPDOWN,
[combo]( wxCommandEvent& aEvent )
{
combo->SetString( combo->GetCount() - 1, _( "Custom..." ) );
} );
return combo; return combo;
} }

View File

@ -221,7 +221,7 @@ private:
* can be nullptr * can be nullptr
* @param aRow = the row index in the wxFlexGridSizer (used to build a wxWidget unique id) * @param aRow = the row index in the wxFlexGridSizer (used to build a wxWidget unique id)
*/ */
wxBitmapComboBox* createBmComboBox( BOARD_STACKUP_ITEM* aStackupItem, int aRow ); wxBitmapComboBox* createColorBox( BOARD_STACKUP_ITEM* aStackupItem, int aRow );
/** /**
* disconnect event handlers connected to wxControl items * disconnect event handlers connected to wxControl items

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2009-2021 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -36,6 +36,9 @@
#include <layer_ids.h> #include <layer_ids.h>
#include <i18n_utility.h> // For _HKI definition #include <i18n_utility.h> // For _HKI definition
#include <gal/color4d.h>
#include <board_stackup_manager/board_stackup.h>
// Keyword used in file to identify the dielectric layer type // Keyword used in file to identify the dielectric layer type
#define KEY_CORE "core" #define KEY_CORE "core"
@ -44,8 +47,7 @@
#define KEY_COPPER "copper" #define KEY_COPPER "copper"
// key string used for not specified parameters // key string used for not specified parameters
// Can be translated in dialogs, and is also a keyword // Can be translated in dialogs, and is also a keyword outside dialogs
// outside dialogs
wxString inline NotSpecifiedPrm() wxString inline NotSpecifiedPrm()
{ {
return _HKI( "Not specified" ); return _HKI( "Not specified" );
@ -58,6 +60,8 @@ wxString inline NotSpecifiedPrm()
*/ */
bool IsPrmSpecified( const wxString& aPrmValue ); bool IsPrmSpecified( const wxString& aPrmValue );
#define DEFAULT_SOLDERMASK_OPACITY 0.83
// A reasonable Epsilon R value for solder mask dielectric // A reasonable Epsilon R value for solder mask dielectric
#define DEFAULT_EPSILON_R_SOLDERMASK 3.3 #define DEFAULT_EPSILON_R_SOLDERMASK 3.3
@ -65,16 +69,34 @@ bool IsPrmSpecified( const wxString& aPrmValue );
#define DEFAULT_EPSILON_R_SILKSCREEN 1.0 #define DEFAULT_EPSILON_R_SILKSCREEN 1.0
// A minor struct to handle color in gerber job file and dialog // A minor struct to handle color in gerber job file and dialog
struct FAB_LAYER_COLOR class FAB_LAYER_COLOR
{ {
wxString m_ColorName; // the name (in job file) of the color public:
// User values are the HTML coding #rrggbb hexa value. FAB_LAYER_COLOR()
wxColor m_Color; // the color in r,g,b values (0..255)
FAB_LAYER_COLOR() {}
FAB_LAYER_COLOR( const wxString& aColorName, const wxColor& aColor )
: m_ColorName( aColorName ), m_Color( aColor )
{} {}
FAB_LAYER_COLOR( const wxString& aColorName, const wxColor& aColor ) :
m_colorName( aColorName ),
m_color( aColor )
{}
const wxString& GetName() const
{
return m_colorName;
}
wxColor GetColor( BOARD_STACKUP_ITEM_TYPE aItemType ) const
{
if( aItemType == BS_ITEM_TYPE_SOLDERMASK )
return m_color.WithAlpha( DEFAULT_SOLDERMASK_OPACITY ).ToColour();
else
return m_color.WithAlpha( 1.0 ).ToColour();
}
private:
wxString m_colorName; // the name (in job file) of the color
// User values are the HTML coding #rrggbbaa hexadecimal value.
KIGFX::COLOR4D m_color;
}; };
@ -99,4 +121,10 @@ int GetColorStandardListCount();
*/ */
int GetColorUserDefinedListIdx(); int GetColorUserDefinedListIdx();
inline wxColour GetDefaultUserColor( BOARD_STACKUP_ITEM_TYPE aType )
{
return GetColorStandardList()[GetColorUserDefinedListIdx()].GetColor( aType );
}
#endif // #ifndef STACKUP_PREDEFINED_PRMS_H #endif // #ifndef STACKUP_PREDEFINED_PRMS_H

View File

@ -1474,7 +1474,18 @@ void PCB_PARSER::parseBoardStackup()
case T_color: case T_color:
NeedSYMBOL(); NeedSYMBOL();
item->SetColor( FromUTF8() ); name = FromUTF8();
// Older versions didn't always store opacity with colors
if( name.StartsWith( "#" ) && name.Length() < 9 )
{
if( item->GetType() == BS_ITEM_TYPE_SOLDERMASK )
name += "FF";
else
name += "D3";
}
item->SetColor( name );
NeedRIGHT(); NeedRIGHT();
break; break;