Add color theme settings to pcbnew

This commit is contained in:
Jon Evans 2020-04-23 21:55:20 -04:00
parent facf40d3ce
commit 2d95270a31
16 changed files with 756 additions and 327 deletions

View File

@ -18,17 +18,40 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <bitmaps.h>
#include <dialogs/dialog_color_picker.h>
#include <launch_ext.h>
#include <layers_id_colors_and_visibility.h>
#include <menus_helpers.h>
#include <panel_color_settings.h>
#include <pgm_base.h>
#include <settings/color_settings.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <validators.h>
// Width and height of every (color-displaying / bitmap) button in dialog units
const wxSize BUTTON_SIZE( 24, 12 );
const wxSize BUTTON_BORDER( 4, 4 );
// Button ID starting point
constexpr int FIRST_BUTTON_ID = 1800;
PANEL_COLOR_SETTINGS::PANEL_COLOR_SETTINGS( wxWindow* aParent ) :
PANEL_COLOR_SETTINGS_BASE( aParent )
PANEL_COLOR_SETTINGS_BASE( aParent ),
m_currentSettings( nullptr ),
m_buttons(),
m_copied( COLOR4D::UNSPECIFIED ),
m_validLayers(),
m_colorNamespace()
{
#ifdef __APPLE__
m_btnOpenFolder->SetLabel( _( "Reveal Themes in Finder" ) );
#endif
m_buttonSizePx = ConvertDialogToPixels( BUTTON_SIZE );
}
@ -37,3 +60,269 @@ void PANEL_COLOR_SETTINGS::OnBtnOpenThemeFolderClicked( wxCommandEvent& event )
wxString dir( SETTINGS_MANAGER::GetColorSettingsPath() );
LaunchExternal( dir );
}
void PANEL_COLOR_SETTINGS::OnBtnResetClicked( wxCommandEvent& event )
{
if( !m_currentSettings )
return;
for( const auto& pair : m_buttons )
{
int layer = pair.first;
wxBitmapButton* button = pair.second;
COLOR4D defaultColor = m_currentSettings->GetDefaultColor( layer );
m_currentSettings->SetColor( layer, defaultColor );
drawButton( button, defaultColor );
}
}
void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
{
int idx = m_cbTheme->GetSelection();
if( idx == static_cast<int>( m_cbTheme->GetCount() ) - 2 )
{
// separator; re-select active theme
m_cbTheme->SetStringSelection( m_currentSettings->GetName() );
return;
}
if( idx == (int)m_cbTheme->GetCount() - 1 )
{
// New Theme...
if( !saveCurrentTheme( false ) )
return;
MODULE_NAME_CHAR_VALIDATOR themeNameValidator;
wxTextEntryDialog dlg( this, _( "New theme name:" ), _( "Add Color Theme" ) );
dlg.SetTextValidator( themeNameValidator );
if( dlg.ShowModal() != wxID_OK )
return;
wxString themeName = dlg.GetValue();
wxFileName fn( themeName + wxT( ".json" ) );
fn.SetPath( SETTINGS_MANAGER::GetColorSettingsPath() );
if( fn.Exists() )
{
wxMessageBox( _( "Theme already exists!" ) );
return;
}
SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
COLOR_SETTINGS* newSettings = settingsMgr.AddNewColorSettings( themeName );
newSettings->SetName( themeName );
for( auto layer : m_validLayers )
newSettings->SetColor( layer, m_currentSettings->GetColor( layer ) );
newSettings->SaveToFile( settingsMgr.GetPathForSettingsFile( newSettings ) );
idx = m_cbTheme->Insert( themeName, idx - 1, static_cast<void*>( newSettings ) );
m_cbTheme->SetSelection( idx );
m_optOverrideColors->SetValue( newSettings->GetOverrideSchItemColors() );
*m_currentSettings = *newSettings;
onNewThemeSelected();
}
else
{
COLOR_SETTINGS* selected = static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( idx ) );
if( selected->GetFilename() != m_currentSettings->GetFilename() )
{
if( !saveCurrentTheme( false ) )
return;
m_optOverrideColors->SetValue( selected->GetOverrideSchItemColors() );
*m_currentSettings = *selected;
onNewThemeSelected();
for( auto pair : m_buttons )
{
drawButton( pair.second, m_currentSettings->GetColor( pair.first ) );
if( pair.first == LAYER_SHEET || pair.first == LAYER_SHEET_BACKGROUND )
pair.second->Show( selected->GetOverrideSchItemColors() );
}
}
}
}
void PANEL_COLOR_SETTINGS::createThemeList( const COLOR_SETTINGS* aCurrent )
{
m_cbTheme->Clear();
for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
{
int pos = m_cbTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
if( settings == aCurrent )
m_cbTheme->SetSelection( pos );
}
m_cbTheme->Append( wxT( "---" ) );
m_cbTheme->Append( _( "New Theme..." ) );
}
void PANEL_COLOR_SETTINGS::createButton( int aLayer, const KIGFX::COLOR4D& aColor,
const wxString& aName )
{
const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT;
const wxSize border = ConvertDialogToPixels( BUTTON_BORDER );
wxStaticText* label = new wxStaticText( m_colorsListWindow, wxID_ANY, aName );
wxMemoryDC iconDC;
wxBitmap bitmap( m_buttonSizePx );
iconDC.SelectObject( bitmap );
iconDC.SetPen( *wxBLACK_PEN );
wxBrush brush;
brush.SetColour( aColor.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y );
int id = FIRST_BUTTON_ID + aLayer;
auto button = new wxBitmapButton( m_colorsListWindow, id, bitmap, wxDefaultPosition,
m_buttonSizePx + border + wxSize( 1, 1 ) );
button->SetToolTip( _( "Edit color (right click for options)" ) );
m_colorsGridSizer->Add( label, 0, flags, 5 );
m_colorsGridSizer->Add( button, 0, flags, 5 );
m_labels[aLayer] = label;
m_buttons[aLayer] = button;
button->Bind( wxEVT_RIGHT_DOWN,
[&, aLayer]( wxMouseEvent& aEvent )
{
ShowColorContextMenu( aEvent, aLayer );
} );
button->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &PANEL_COLOR_SETTINGS::SetColor, this );
}
void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLayer )
{
auto selected =
static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( m_cbTheme->GetSelection() ) );
COLOR4D current = m_currentSettings->GetColor( aLayer );
COLOR4D saved = selected->GetColor( aLayer );
wxMenu menu;
AddMenuItem( &menu, ID_COPY, _( "Copy color" ), KiBitmap( copy_xpm ) );
if( m_copied != COLOR4D::UNSPECIFIED )
AddMenuItem( &menu, ID_PASTE, _( "Paste color" ), KiBitmap( paste_xpm ) );
if( current != saved )
AddMenuItem( &menu, ID_REVERT, _( "Revert to saved color" ), KiBitmap( undo_xpm ) );
menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
[&]( wxCommandEvent& aCmd ) {
switch( aCmd.GetId() )
{
case ID_COPY:
m_copied = current;
break;
case ID_PASTE:
updateColor( aLayer, m_copied );
break;
case ID_REVERT:
updateColor( aLayer, saved );
break;
default:
aCmd.Skip();
}
} );
PopupMenu( &menu );
}
void PANEL_COLOR_SETTINGS::SetColor( wxCommandEvent& event )
{
auto button = static_cast<wxBitmapButton*>( event.GetEventObject() );
auto layer = static_cast<SCH_LAYER_ID>( button->GetId() - FIRST_BUTTON_ID );
COLOR4D oldColor = m_currentSettings->GetColor( layer );
COLOR4D newColor = COLOR4D::UNSPECIFIED;
DIALOG_COLOR_PICKER dialog( this, oldColor, false );
if( dialog.ShowModal() == wxID_OK )
newColor = dialog.GetColor();
if( newColor == COLOR4D::UNSPECIFIED || oldColor == newColor )
return;
updateColor( layer, newColor );
}
void PANEL_COLOR_SETTINGS::drawButton( wxBitmapButton* aButton, const COLOR4D& aColor ) const
{
wxMemoryDC iconDC;
wxBitmap bitmap = aButton->GetBitmapLabel();
iconDC.SelectObject( bitmap );
iconDC.SetPen( *wxBLACK_PEN );
wxBrush brush;
brush.SetColour( aColor.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y );
aButton->SetBitmapLabel( bitmap );
aButton->Refresh();
}
void PANEL_COLOR_SETTINGS::updateColor( int aLayer, const KIGFX::COLOR4D& aColor )
{
if( m_currentSettings )
m_currentSettings->SetColor( aLayer, aColor );
drawButton( m_buttons[aLayer], aColor );
onColorChanged();
}
bool PANEL_COLOR_SETTINGS::saveCurrentTheme( bool aValidate )
{
if( aValidate && !validateSave() )
return false;
SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
COLOR_SETTINGS* selected = settingsMgr.GetColorSettings( m_currentSettings->GetFilename() );
selected->SetOverrideSchItemColors( m_optOverrideColors->GetValue() );
for( auto layer : m_validLayers )
selected->SetColor( layer, m_currentSettings->GetColor( layer ) );
settingsMgr.SaveColorSettings( selected, m_colorNamespace );
return true;
}

View File

@ -21,9 +21,13 @@
#ifndef PANEL_COLOR_SETTINGS_H
#define PANEL_COLOR_SETTINGS_H
#include <gal/color4d.h>
#include <panel_color_settings_base.h>
class COLOR_SETTINGS;
class PANEL_COLOR_SETTINGS : public PANEL_COLOR_SETTINGS_BASE
{
public:
@ -31,8 +35,80 @@ public:
~PANEL_COLOR_SETTINGS() = default;
enum COLOR_CONTEXT_ID
{
ID_COPY = wxID_HIGHEST + 1,
ID_PASTE,
ID_REVERT
};
protected:
void OnBtnOpenThemeFolderClicked( wxCommandEvent& event ) override;
void OnBtnResetClicked( wxCommandEvent& aEvent ) override;
void OnThemeChanged( wxCommandEvent& aEvent ) override;
void ShowColorContextMenu( wxMouseEvent& aEvent, int aLayer );
void SetColor( wxCommandEvent& aEvent );
void createThemeList( const COLOR_SETTINGS* aCurrent );
void createButton( int aLayer, const KIGFX::COLOR4D& aColor, const wxString& aName );
void updateColor( int aLayer, const KIGFX::COLOR4D& aColor );
void drawButton( wxBitmapButton* aButton, const KIGFX::COLOR4D& aColor ) const;
virtual bool saveCurrentTheme( bool aValidate );
/**
* Performs a pre-save validation of the current color theme.
* @param aQuiet will suppress any warning output (prompt dialogs)
* @return true if save is allowed
*/
virtual bool validateSave( bool aQuiet = false )
{
return true;
}
/**
* Event fired when a new theme is selected that can be overridden in children
*/
virtual void onNewThemeSelected() {}
/**
* Event fired when the user changes any color
*/
virtual void onColorChanged() {}
COLOR_SETTINGS* m_currentSettings;
wxSize m_buttonSizePx;
std::map<int, wxStaticText*> m_labels;
std::map<int, wxBitmapButton*> m_buttons;
KIGFX::COLOR4D m_copied;
/**
* A list of layer IDs that are valid for the current color settings dialog.
*
* Valid colors will be shown for editing and are the set of colors that actions like resetting
* to defaults will apply to.
*
* This list must be filled in the application-specific color settings panel constructors.
*/
std::vector<int> m_validLayers;
/**
* A namespace that will be passed to SETTINGS_MANAGER::SaveColorSettings
*
* This should be set to the appropriate namespace in the application-specific constructor
*/
std::string m_colorNamespace;
};

View File

@ -21,10 +21,12 @@
#include <wx/wx.h>
wxString LayerName( SCH_LAYER_ID aLayer )
wxString LayerName( int aLayer )
{
switch( aLayer )
{
// SCH_LAYER_ID
case LAYER_WIRE:
return _( "Wire" );
@ -127,7 +129,93 @@ wxString LayerName( SCH_LAYER_ID aLayer )
case LAYER_SCHEMATIC_WORKSHEET:
return _( "Worksheet" );
// GAL_LAYER_ID
case LAYER_MOD_FR:
return _( "Footprints Front" );
case LAYER_MOD_BK:
return _( "Footprints Back" );
case LAYER_MOD_VALUES:
return _( "Values" );
case LAYER_MOD_REFERENCES:
return _( "Reference Designators" );
case LAYER_MOD_TEXT_FR:
return _( "Footprint Text Front" );
case LAYER_MOD_TEXT_BK:
return _( "Footprint Text Back" );
case LAYER_MOD_TEXT_INVISIBLE:
return _( "Hidden Text" );
case LAYER_PAD_FR:
return _( "Pads Front" );
case LAYER_PAD_BK:
return _( "Pads Back" );
case LAYER_PADS_TH:
return _( "Through Hole Pads" );
case LAYER_TRACKS:
return _( "Tracks" );
case LAYER_VIA_THROUGH:
return _( "Through Via" );
case LAYER_VIA_BBLIND:
return _( "Bl/Buried Via" );
case LAYER_VIA_MICROVIA:
return _( "Micro Via" );
case LAYER_NON_PLATEDHOLES:
return _( "Non Plated Holes" );
case LAYER_RATSNEST:
return _( "Ratsnest" );
case LAYER_NO_CONNECTS:
return _( "No-Connects" );
case LAYER_DRC_WARNING:
return _( "DRC Warnings" );
case LAYER_DRC_ERROR:
return _( "DRC Errors" );
case LAYER_ANCHOR:
return _( "Anchors" );
case LAYER_WORKSHEET:
return _( "Worksheet" );
case LAYER_CURSOR:
return _( "Cursor" );
case LAYER_AUX_ITEMS:
return _( "Aux Items" );
case LAYER_GRID:
return _( "Grid" );
case LAYER_PCB_BACKGROUND:
return _( "Background" );
case LAYER_SELECT_OVERLAY:
return _( "Selection highlight" );
default:
#if DEBUG
wxString str;
str.Printf( "Unknown: ID %d", aLayer );
return str;
#else
return wxEmptyString;
#endif
}
}
}

View File

@ -60,15 +60,12 @@ PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aF
PANEL_COLOR_SETTINGS( aParent ),
m_frame( aFrame ),
m_preview( nullptr ),
m_currentSettings( nullptr ),
m_page( nullptr ),
m_titleBlock( nullptr ),
m_ws( nullptr ),
m_previewItems(),
m_buttons(),
m_copied( COLOR4D::UNSPECIFIED )
m_previewItems()
{
m_buttonSizePx = ConvertDialogToPixels( BUTTON_SIZE );
m_colorNamespace = "schematic";
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
@ -78,23 +75,17 @@ PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aF
EESCHEMA_SETTINGS* app_settings = mgr.GetAppSettings<EESCHEMA_SETTINGS>();
COLOR_SETTINGS* current = mgr.GetColorSettings( app_settings->m_ColorTheme );
m_cbTheme->Clear();
for( COLOR_SETTINGS* settings : mgr.GetColorSettingsList() )
{
int pos = m_cbTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
if( settings == current )
m_cbTheme->SetSelection( pos );
}
m_cbTheme->Append( wxT( "---" ) );
m_cbTheme->Append( _( "New Theme..." ) );
createThemeList( current );
m_optOverrideColors->SetValue( current->GetOverrideSchItemColors() );
m_currentSettings = new COLOR_SETTINGS( *current );
for( int id = SCH_LAYER_ID_START; id < SCH_LAYER_ID_END; id++ )
m_validLayers.push_back( id );
createButtons();
KIGFX::GAL_DISPLAY_OPTIONS options;
options.ReadConfig( *common_settings, app_settings->m_Window, this );
options.m_forceDisplayCursor = false;
@ -106,12 +97,6 @@ PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aF
m_preview->SetStealsFocus( false );
m_preview->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
createButtons();
Connect( FIRST_BUTTON_ID, FIRST_BUTTON_ID + ( SCH_LAYER_ID_END - SCH_LAYER_ID_START ),
wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler( PANEL_EESCHEMA_COLOR_SETTINGS::SetColor ) );
m_colorsMainSizer->Add( 10, 0, 0, wxEXPAND, 5 );
m_colorsMainSizer->Add( m_preview, 1, wxALL | wxEXPAND, 5 );
m_colorsMainSizer->Add( 10, 0, 0, wxEXPAND, 5 );
@ -156,60 +141,53 @@ bool PANEL_EESCHEMA_COLOR_SETTINGS::TransferDataToWindow()
}
bool PANEL_EESCHEMA_COLOR_SETTINGS::saveCurrentTheme( bool aValidate )
bool PANEL_EESCHEMA_COLOR_SETTINGS::validateSave( bool aQuiet )
{
if( aValidate )
{
COLOR4D bgcolor = m_currentSettings->GetColor( LAYER_SCHEMATIC_BACKGROUND );
for( SCH_LAYER_ID layer = SCH_LAYER_ID_START; layer < SCH_LAYER_ID_END; ++layer )
{
if( bgcolor == m_currentSettings->GetColor( layer )
&& layer != LAYER_SCHEMATIC_BACKGROUND && layer != LAYER_SHEET_BACKGROUND )
{
wxString msg = _( "Some items have the same color as the background\n"
"and they will not be seen on the screen. Are you\n"
"sure you want to use these colors?" );
if( wxMessageBox( msg, _( "Warning" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
return false;
break;
}
}
}
SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
COLOR_SETTINGS* selected = settingsMgr.GetColorSettings( m_currentSettings->GetFilename() );
selected->SetOverrideSchItemColors( m_optOverrideColors->GetValue() );
COLOR4D bgcolor = m_currentSettings->GetColor( LAYER_SCHEMATIC_BACKGROUND );
for( SCH_LAYER_ID layer = SCH_LAYER_ID_START; layer < SCH_LAYER_ID_END; ++layer )
{
COLOR4D color = m_currentSettings->GetColor( layer );
// Do not allow non-background layers to be completely white.
// This ensures the BW printing recognizes that the colors should be printed black.
if( color == COLOR4D::WHITE
&& layer != LAYER_SCHEMATIC_BACKGROUND && layer != LAYER_SHEET_BACKGROUND )
if( bgcolor == m_currentSettings->GetColor( layer )
&& layer != LAYER_SCHEMATIC_BACKGROUND && layer != LAYER_SHEET_BACKGROUND )
{
color.Darken( 0.01 );
wxString msg = _( "Some items have the same color as the background\n"
"and they will not be seen on the screen. Are you\n"
"sure you want to use these colors?" );
if( wxMessageBox( msg, _( "Warning" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
return false;
break;
}
selected->SetColor( layer, color );
}
settingsMgr.SaveColorSettings( selected, "schematic" );
return true;
}
bool PANEL_EESCHEMA_COLOR_SETTINGS::saveCurrentTheme( bool aValidate)
{
for( auto layer : m_validLayers )
{
COLOR4D color = m_currentSettings->GetColor( layer );
// Do not allow non-background layers to be completely white.
// This ensures the BW printing recognizes that the colors should be printed black.
if( color == COLOR4D::WHITE && layer != LAYER_SCHEMATIC_BACKGROUND
&& layer != LAYER_SHEET_BACKGROUND )
{
color.Darken( 0.01 );
}
m_currentSettings->SetColor( layer, color );
}
return PANEL_COLOR_SETTINGS::saveCurrentTheme( aValidate );
}
void PANEL_EESCHEMA_COLOR_SETTINGS::createButtons()
{
const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxRIGHT;
wxSize border = ConvertDialogToPixels( BUTTON_BORDER );
std::vector<SCH_LAYER_ID> layers;
for( SCH_LAYER_ID i = SCH_LAYER_ID_START; i < SCH_LAYER_ID_END; ++i )
@ -221,69 +199,14 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createButtons()
return LayerName( a ) < LayerName( b );
} );
for( SCH_LAYER_ID layer : layers )
{
wxString name = LayerName( layer );
wxStaticText* label = new wxStaticText( m_colorsListWindow, wxID_ANY, name );
COLOR4D color = m_currentSettings->GetColor( layer );
wxMemoryDC iconDC;
wxBitmap bitmap( m_buttonSizePx );
iconDC.SelectObject( bitmap );
iconDC.SetPen( *wxBLACK_PEN );
wxBrush brush;
brush.SetColour( color.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y );
int id = FIRST_BUTTON_ID + ( layer - SCH_LAYER_ID_START );
auto button = new wxBitmapButton( m_colorsListWindow, id, bitmap, wxDefaultPosition,
m_buttonSizePx + border + wxSize( 1, 1 ) );
button->SetToolTip( _( "Edit color (right click for options)" ) );
// If the theme is not overriding individual item colors then don't show them so that
// the user doesn't get seduced into thinking they'll have some effect.
if( layer == LAYER_SHEET || layer == LAYER_SHEET_BACKGROUND )
{
label->Show( m_currentSettings->GetOverrideSchItemColors() );
button->Show( m_currentSettings->GetOverrideSchItemColors() );
}
m_colorsGridSizer->Add( label, 0, flags, 5 );
m_colorsGridSizer->Add( button, 0, flags, 5 );
m_labels[layer] = label;
m_buttons[layer] = button;
button->Bind( wxEVT_RIGHT_DOWN,
[&, layer]( wxMouseEvent& aEvent )
{
ShowColorContextMenu( aEvent, layer );
} );
}
for( int layer : layers )
createButton( layer, m_currentSettings->GetColor( layer ), LayerName( layer ) );
}
void PANEL_EESCHEMA_COLOR_SETTINGS::drawButton( wxBitmapButton* aButton, const COLOR4D& aColor )
void PANEL_EESCHEMA_COLOR_SETTINGS::onNewThemeSelected()
{
wxMemoryDC iconDC;
wxBitmap bitmap = aButton->GetBitmapLabel();
iconDC.SelectObject( bitmap );
iconDC.SetPen( *wxBLACK_PEN );
wxBrush brush;
brush.SetColour( aColor.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, m_buttonSizePx.x, m_buttonSizePx.y );
aButton->SetBitmapLabel( bitmap );
aButton->Refresh();
updatePreview();
}
@ -407,49 +330,15 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
}
void PANEL_EESCHEMA_COLOR_SETTINGS::SetColor( wxCommandEvent& event )
void PANEL_EESCHEMA_COLOR_SETTINGS::onColorChanged()
{
auto button = static_cast<wxBitmapButton*>( event.GetEventObject() );
auto layer =
static_cast<SCH_LAYER_ID>( button->GetId() - FIRST_BUTTON_ID + SCH_LAYER_ID_START );
COLOR4D oldColor = m_currentSettings->GetColor( layer );
COLOR4D newColor = COLOR4D::UNSPECIFIED;
DIALOG_COLOR_PICKER dialog( this, oldColor, false );
if( dialog.ShowModal() == wxID_OK )
newColor = dialog.GetColor();
if( newColor == COLOR4D::UNSPECIFIED || oldColor == newColor )
return;
updateColor( layer, newColor );
}
void PANEL_EESCHEMA_COLOR_SETTINGS::updateColor( SCH_LAYER_ID aLayer, const KIGFX::COLOR4D& aColor )
{
m_currentSettings->SetColor( aLayer, aColor );
drawButton( m_buttons[aLayer], aColor );
updatePreview();
}
void PANEL_EESCHEMA_COLOR_SETTINGS::OnBtnResetClicked( wxCommandEvent& event )
{
for( const auto& pair : m_buttons )
{
SCH_LAYER_ID layer = pair.first;
wxBitmapButton* button = pair.second;
COLOR4D defaultColor = m_currentSettings->GetDefaultColor( layer );
m_currentSettings->SetColor( layer, defaultColor );
drawButton( button, defaultColor );
}
PANEL_COLOR_SETTINGS::OnBtnResetClicked( event );
updatePreview();
}
@ -492,83 +381,6 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::OnSize( wxSizeEvent& aEvent )
}
void PANEL_EESCHEMA_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
{
int idx = m_cbTheme->GetSelection();
if( idx == (int)m_cbTheme->GetCount() - 2 )
{
// separator; re-select active theme
m_cbTheme->SetStringSelection( m_currentSettings->GetName() );
return;
}
if( idx == (int)m_cbTheme->GetCount() - 1 )
{
// New Theme...
if( !saveCurrentTheme( false ) )
return;
MODULE_NAME_CHAR_VALIDATOR themeNameValidator;
wxTextEntryDialog dlg( this, _( "New theme name:" ), _( "Add Color Theme" ) );
dlg.SetTextValidator( themeNameValidator );
if( dlg.ShowModal() != wxID_OK )
return;
wxString themeName = dlg.GetValue();
wxFileName fn( themeName + wxT( ".json" ) );
fn.SetPath( SETTINGS_MANAGER::GetColorSettingsPath() );
if( fn.Exists() )
{
wxMessageBox( _( "Theme already exists!" ) );
return;
}
SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
COLOR_SETTINGS* newSettings = settingsMgr.AddNewColorSettings( themeName );
newSettings->SetName( themeName );
for( SCH_LAYER_ID layer = SCH_LAYER_ID_START; layer < SCH_LAYER_ID_END; ++layer )
newSettings->SetColor( layer, m_currentSettings->GetColor( layer ) );
newSettings->SaveToFile( settingsMgr.GetPathForSettingsFile( newSettings ) );
idx = m_cbTheme->Insert( themeName, idx - 1, static_cast<void*>( newSettings ) );
m_cbTheme->SetSelection( idx );
m_optOverrideColors->SetValue( newSettings->GetOverrideSchItemColors() );
*m_currentSettings = *newSettings;
}
else
{
COLOR_SETTINGS* selected = static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( idx ) );
if( selected->GetFilename() != m_currentSettings->GetFilename() )
{
if( !saveCurrentTheme( false ) )
return;
m_optOverrideColors->SetValue( selected->GetOverrideSchItemColors() );
*m_currentSettings = *selected;
updatePreview();
for( auto pair : m_buttons )
{
drawButton( pair.second, m_currentSettings->GetColor( pair.first ) );
if( pair.first == LAYER_SHEET || pair.first == LAYER_SHEET_BACKGROUND )
pair.second->Show( selected->GetOverrideSchItemColors() );
}
}
}
}
void PANEL_EESCHEMA_COLOR_SETTINGS::OnOverrideItemColorsClicked( wxCommandEvent& aEvent )
{
m_currentSettings->SetOverrideSchItemColors( m_optOverrideColors->GetValue() );
@ -584,46 +396,3 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::OnOverrideItemColorsClicked( wxCommandEvent&
m_colorsGridSizer->Layout();
m_colorsListWindow->Layout();
}
void PANEL_EESCHEMA_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent,
SCH_LAYER_ID aLayer )
{
auto selected =
static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( m_cbTheme->GetSelection() ) );
COLOR4D current = m_currentSettings->GetColor( aLayer );
COLOR4D saved = selected->GetColor( aLayer );
wxMenu menu;
AddMenuItem( &menu, ID_COPY, _( "Copy color" ), KiBitmap( copy_xpm ) );
if( m_copied != COLOR4D::UNSPECIFIED )
AddMenuItem( &menu, ID_PASTE, _( "Paste color" ), KiBitmap( paste_xpm ) );
if( current != saved )
AddMenuItem( &menu, ID_REVERT, _( "Revert to saved color" ), KiBitmap( undo_xpm ) );
menu.Bind( wxEVT_COMMAND_MENU_SELECTED, [&]( wxCommandEvent& aCmd ) {
switch( aCmd.GetId() )
{
case ID_COPY:
m_copied = current;
break;
case ID_PASTE:
updateColor( aLayer, m_copied );
break;
case ID_REVERT:
updateColor( aLayer, saved );
break;
default:
aCmd.Skip();
}
} );
PopupMenu( &menu );
}

View File

@ -49,31 +49,25 @@ protected:
bool TransferDataToWindow() override;
void SetColor( wxCommandEvent& aEvent );
void OnThemeChanged( wxCommandEvent& aEvent ) override;
void OnOverrideItemColorsClicked( wxCommandEvent& aEvent ) override;
void OnBtnResetClicked( wxCommandEvent& aEvent ) override;
void OnSize( wxSizeEvent& aEvent ) override;
void ShowColorContextMenu( wxMouseEvent& aEvent, SCH_LAYER_ID aLayer );
void OnBtnResetClicked( wxCommandEvent& event ) override;
enum COLOR_CONTEXT_ID
{
ID_COPY = wxID_HIGHEST + 1,
ID_PASTE,
ID_REVERT
};
bool validateSave( bool aQuiet = false ) override;
bool saveCurrentTheme( bool aValidate ) override;
void onNewThemeSelected() override;
void onColorChanged() override;
private:
SCH_BASE_FRAME* m_frame;
SCH_PREVIEW_PANEL* m_preview;
COLOR_SETTINGS* m_currentSettings;
wxSize m_buttonSizePx;
PAGE_INFO* m_page;
TITLE_BLOCK* m_titleBlock;
@ -82,20 +76,10 @@ private:
std::vector<EDA_ITEM*> m_previewItems;
std::map<SCH_LAYER_ID, wxStaticText*> m_labels;
std::map<SCH_LAYER_ID, wxBitmapButton*> m_buttons;
KIGFX::COLOR4D m_copied;
bool saveCurrentTheme( bool aValidate );
void createPreviewItems();
void createButtons();
void updateColor( SCH_LAYER_ID aLayer, const KIGFX::COLOR4D& aColor );
void drawButton( wxBitmapButton* aButton, const KIGFX::COLOR4D& aColor );
void updatePreview();

View File

@ -374,7 +374,7 @@ void SCH_EDIT_FRAME::SaveProjectSettings()
fn.SetExt( ProjectFileExtension );
if( !IsWritable( fn ) )
if( !fn.HasName() || !IsWritable( fn ) )
return;
wxString path = fn.GetFullPath();

View File

@ -348,8 +348,11 @@ enum LAYER_3D_ID : int
#define LAYER_ID_COUNT FPEDIT_LAYER_ID_END
/// Returns the string equivalent of a given layer
wxString LayerName( SCH_LAYER_ID aLayer );
/**
* Returns the string equivalent of a given layer
* @param aLayer is a valid layer ID
*/
wxString LayerName( int aLayer );
// Some elements do not have yet a visibility control

View File

@ -151,6 +151,7 @@ set( PCBNEW_DIALOGS
dialogs/panel_modedit_display_options.cpp
dialogs/panel_modedit_settings.cpp
dialogs/panel_modedit_settings_base.cpp
dialogs/panel_pcbnew_color_settings.cpp
dialogs/panel_pcbnew_display_options.cpp
dialogs/panel_pcbnew_display_options_base.cpp
dialogs/panel_pcbnew_settings.cpp

View File

@ -0,0 +1,135 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <regex>
#include <class_board.h>
#include <gal/gal_display_options.h>
#include <layers_id_colors_and_visibility.h>
#include <panel_pcbnew_color_settings.h>
#include <pcbnew_settings.h>
#include <pcb_edit_frame.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
PANEL_PCBNEW_COLOR_SETTINGS::PANEL_PCBNEW_COLOR_SETTINGS( PCB_EDIT_FRAME* aFrame,
wxWindow* aParent )
: PANEL_COLOR_SETTINGS( aParent ),
m_frame( aFrame ),
m_page( nullptr ),
m_titleBlock( nullptr ),
m_ws( nullptr )
{
// Currently this only applies to eeschema
m_optOverrideColors->Hide();
m_colorNamespace = "board";
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
mgr.ReloadColorSettings();
PCBNEW_SETTINGS* app_settings = mgr.GetAppSettings<PCBNEW_SETTINGS>();
COLOR_SETTINGS* current = mgr.GetColorSettings( app_settings->m_ColorTheme );
m_optOverrideColors->SetValue( current->GetOverrideSchItemColors() );
m_currentSettings = new COLOR_SETTINGS( *current );
createThemeList( current );
for( int id = GAL_LAYER_ID_START; id < GAL_LAYER_ID_END; id++ )
m_validLayers.push_back( id );
for( int id = F_Cu; id < PCB_LAYER_ID_COUNT; id++ )
m_validLayers.push_back( id );
m_colorsMainSizer->Insert( 0, 10, 0, 0, wxEXPAND, 5 );
createButtons();
}
PANEL_PCBNEW_COLOR_SETTINGS::~PANEL_PCBNEW_COLOR_SETTINGS()
{
delete m_page;
delete m_titleBlock;
}
bool PANEL_PCBNEW_COLOR_SETTINGS::TransferDataFromWindow()
{
m_currentSettings->SetOverrideSchItemColors( m_optOverrideColors->GetValue() );
if( !saveCurrentTheme( true ) )
return false;
m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings()->LoadColors( m_currentSettings );
SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
PCBNEW_SETTINGS* app_settings = settingsMgr.GetAppSettings<PCBNEW_SETTINGS>();
app_settings->m_ColorTheme = m_currentSettings->GetFilename();
m_frame->ReFillLayerWidget();
m_frame->SyncRenderStates();
return true;
}
bool PANEL_PCBNEW_COLOR_SETTINGS::TransferDataToWindow()
{
return true;
}
void PANEL_PCBNEW_COLOR_SETTINGS::createButtons()
{
std::vector<int> layers;
for( GAL_LAYER_ID i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; ++i )
{
if( m_currentSettings->GetColor( i ) != COLOR4D::UNSPECIFIED )
layers.push_back( i );
}
std::sort( layers.begin(), layers.end(),
[]( int a, int b )
{
return LayerName( a ) < LayerName( b );
} );
// Don't sort board layers by name
for( int i = PCBNEW_LAYER_ID_START; i < PCB_LAYER_ID_COUNT; ++i )
layers.insert( layers.begin() + i, i );
BOARD* board = m_frame->GetBoard();
for( int layer : layers )
{
wxString name = LayerName( layer );
if( board && layer >= PCBNEW_LAYER_ID_START && layer < PCB_LAYER_ID_COUNT )
name = board->GetLayerName( static_cast<PCB_LAYER_ID>( layer ) );
createButton( layer, m_currentSettings->GetColor( layer ), name );
}
}

View File

@ -0,0 +1,70 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PANEL_PCBNEW_COLOR_SETTINGS_H_
#define PANEL_PCBNEW_COLOR_SETTINGS_H_
#include <gal/color4d.h>
#include <layers_id_colors_and_visibility.h>
#include <panel_color_settings.h>
class COLOR_SETTINGS;
class PAGE_INFO;
class PCB_EDIT_FRAME;
class TITLE_BLOCK;
namespace KIGFX
{
class WS_PROXY_VIEW_ITEM;
}
class PANEL_PCBNEW_COLOR_SETTINGS : public PANEL_COLOR_SETTINGS
{
public:
PANEL_PCBNEW_COLOR_SETTINGS( PCB_EDIT_FRAME* aFrame, wxWindow* aParent );
~PANEL_PCBNEW_COLOR_SETTINGS() override;
protected:
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
enum COLOR_CONTEXT_ID
{
ID_COPY = wxID_HIGHEST + 1,
ID_PASTE,
ID_REVERT
};
private:
PCB_EDIT_FRAME* m_frame;
PAGE_INFO* m_page;
TITLE_BLOCK* m_titleBlock;
KIGFX::WS_PROXY_VIEW_ITEM* m_ws;
void createButtons();
};
#endif

View File

@ -316,7 +316,7 @@ void PCB_BASE_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
COLOR_SETTINGS* PCB_BASE_FRAME::ColorSettings()
{
return Pgm().GetSettingsManager().GetColorSettings();
return Pgm().GetSettingsManager().GetColorSettings( GetSettings()->m_ColorTheme );
}

View File

@ -36,6 +36,7 @@
#include <class_track.h>
#include <class_marker_pcb.h>
#include <pcb_base_frame.h>
#include <pcbnew_settings.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <confirm.h>
@ -204,10 +205,17 @@ void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet )
void PCB_DRAW_PANEL_GAL::UpdateColors()
{
COLOR_SETTINGS* cs = Pgm().GetSettingsManager().GetColorSettings();
COLOR_SETTINGS* cs = nullptr;
auto frame = dynamic_cast<PCB_BASE_FRAME*>( GetParentEDAFrame() );
if( frame )
cs = frame->ColorSettings();
else
Pgm().GetSettingsManager().GetColorSettings();
wxASSERT( cs );
if( frame && frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
cs->SetColorContext( COLOR_CONTEXT::FOOTPRINT );
else
@ -220,6 +228,7 @@ void PCB_DRAW_PANEL_GAL::UpdateColors()
m_gal->SetCursorColor( cs->GetColor( LAYER_CURSOR ) );
}
void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer )
{
// Set display settings for high contrast mode

View File

@ -724,7 +724,7 @@ void PCB_EDIT_FRAME::onBoardLoaded()
// Sync layer and item visibility
syncLayerVisibilities();
syncLayerWidgetLayer();
syncRenderStates();
SyncRenderStates();
SetElementVisibility( LAYER_RATSNEST, GetDisplayOptions().m_ShowGlobalRatsnest );
@ -750,7 +750,7 @@ void PCB_EDIT_FRAME::syncLayerWidgetLayer()
}
void PCB_EDIT_FRAME::syncRenderStates()
void PCB_EDIT_FRAME::SyncRenderStates()
{
m_Layers->ReFillRender();
}
@ -811,12 +811,12 @@ void PCB_EDIT_FRAME::ShowChangedLanguage()
m_Layers->SetLayersManagerTabsText();
ReFillLayerWidget();
// m_Layers->ReFillRender(); // syncRenderStates() does this
// m_Layers->ReFillRender(); // SyncRenderStates() does this
// upate the layer widget to match board visibility states, both layers and render columns.
syncLayerVisibilities();
syncLayerWidgetLayer();
syncRenderStates();
SyncRenderStates();
m_Layers->Thaw();
@ -900,12 +900,12 @@ void PCB_EDIT_FRAME::UpdateUserInterface()
// Update the layer manager
m_Layers->Freeze();
ReFillLayerWidget();
// m_Layers->ReFillRender(); // syncRenderStates() does this
// m_Layers->ReFillRender(); // SyncRenderStates() does this
// upate the layer widget to match board visibility states, both layers and render columns.
syncLayerVisibilities();
syncLayerWidgetLayer();
syncRenderStates();
SyncRenderStates();
m_Layers->Thaw();
}
@ -948,7 +948,7 @@ void PCB_EDIT_FRAME::SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType )
// layer widget to match board visibility states, both layers and render columns.
syncLayerVisibilities();
syncLayerWidgetLayer();
syncRenderStates();
SyncRenderStates();
}

View File

@ -222,14 +222,6 @@ protected:
*/
void syncLayerWidgetLayer();
/**
* Function syncRenderStates
* updates the "Render" checkboxes in the layer widget according
* to current toggle values determined by IsElementVisible(), and is helpful
* immediately after loading a BOARD which may have state information in it.
*/
void syncRenderStates();
/**
* Function syncLayerVisibilities
* updates each "Layer" checkbox in the layer widget according
@ -535,6 +527,13 @@ public:
*/
void ReFillLayerWidget();
/**
* Updates the "Render" colors and checkboxes in the layer widget according
* to current toggle values determined by IsElementVisible(), and is helpful
* immediately after loading a BOARD which may have state information in it.
*/
void SyncRenderStates();
///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
void ActivateGalCanvas() override;

View File

@ -28,6 +28,7 @@
#include <math/util.h> // for KiROUND
#include <pcb_plot_params.h>
#include <pcb_plot_params_parser.h>
#include <pcbnew_settings.h>
#include <pgm_base.h>
#include <plotter.h>
#include <settings/color_settings.h>
@ -148,8 +149,11 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
if( PgmOrNull() )
{
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
auto app = mgr.GetAppSettings<PCBNEW_SETTINGS>();
m_colors = mgr.GetColorSettings( app->m_ColorTheme );
m_default_colors = nullptr;
m_colors = Pgm().GetSettingsManager().GetColorSettings();
}
else
{

View File

@ -36,6 +36,7 @@
#include <ws_painter.h>
#include <panel_hotkeys_editor.h>
#include <panel_pcbnew_settings.h>
#include <panel_pcbnew_color_settings.h>
#include <panel_pcbnew_display_options.h>
#include <panel_pcbnew_action_plugins.h>
#include <fp_lib_table.h>
@ -64,6 +65,7 @@ void PCB_EDIT_FRAME::InstallPreferences( PAGED_DIALOG* aParent,
book->AddPage( new wxPanel( book ), _( "Pcbnew" ) );
book->AddSubPage( new PANEL_PCBNEW_DISPLAY_OPTIONS( this, aParent ), _( "Display Options" ) );
book->AddSubPage( new PANEL_PCBNEW_COLOR_SETTINGS( this, aParent ), _( "Colors" ) );
book->AddSubPage( new PANEL_PCBNEW_SETTINGS( this, aParent ), _( "Editing Options" ) );
#if defined(KICAD_SCRIPTING) && defined(KICAD_SCRIPTING_ACTION_MENU)
book->AddSubPage( new PANEL_PCBNEW_ACTION_PLUGINS( this, aParent ), _( "Action Plugins" ) );