KiCad PCB EDA Suite
color_settings.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
22 #include <pgm_base.h>
25 #include <settings/parameters.h>
27 #include <wx/log.h>
28 
29 #include "builtin_color_themes.h"
30 
31 
33 const int colorsSchemaVersion = 2;
34 
35 
36 COLOR_SETTINGS::COLOR_SETTINGS( wxString aFilename ) :
38  m_overrideSchItemColors( false )
39 {
40 
41  m_params.emplace_back( new PARAM<wxString>( "meta.name", &m_displayName, "KiCad Default" ) );
42 
43  std::vector<COLOR4D> default_palette = {
44  CSS_COLOR( 200, 52, 52, 1 ),
45  CSS_COLOR( 127, 200, 127, 1 ),
46  CSS_COLOR( 206, 125, 44, 1 ),
47  CSS_COLOR( 79, 203, 203, 1 ),
48  CSS_COLOR( 219, 98, 139, 1 ),
49  CSS_COLOR( 167, 165, 198, 1 ),
50  CSS_COLOR( 40, 204, 217, 1 ),
51  CSS_COLOR( 232, 178, 167, 1 ),
52  CSS_COLOR( 242, 237, 161, 1 ),
53  CSS_COLOR( 141, 203, 129, 1 ),
54  CSS_COLOR( 237, 124, 51, 1 ),
55  CSS_COLOR( 91, 195, 235, 1 ),
56  CSS_COLOR( 247, 111, 142, 1 ),
57  CSS_COLOR( 77, 127, 196, 1 )
58  };
59 
60  // TODO(JE) in actual usage, how long does the default palette need to be?
61  m_params.emplace_back( new PARAM_LIST<COLOR4D>( "palette", &m_Palette, default_palette ) );
62 
63  m_params.emplace_back( new PARAM<bool>( "schematic.override_item_colors",
64  &m_overrideSchItemColors, false ) );
65 
66 #define CLR( x, y ) \
67  wxASSERT( s_defaultTheme.count( y ) ); \
68  m_params.emplace_back( new COLOR_MAP_PARAM( x, y, s_defaultTheme.at( y ), &m_colors ) );
69 
70  CLR( "schematic.aux_items", LAYER_SCHEMATIC_AUX_ITEMS );
71  CLR( "schematic.background", LAYER_SCHEMATIC_BACKGROUND );
72  CLR( "schematic.brightened", LAYER_BRIGHTENED );
73  CLR( "schematic.bus", LAYER_BUS );
74  CLR( "schematic.bus_junction", LAYER_BUS_JUNCTION );
75  CLR( "schematic.component_body", LAYER_DEVICE_BACKGROUND );
76  CLR( "schematic.component_outline", LAYER_DEVICE );
77  CLR( "schematic.cursor", LAYER_SCHEMATIC_CURSOR );
78  CLR( "schematic.erc_error", LAYER_ERC_ERR );
79  CLR( "schematic.erc_warning", LAYER_ERC_WARN );
80  CLR( "schematic.fields", LAYER_FIELDS );
81  CLR( "schematic.grid", LAYER_SCHEMATIC_GRID );
82  CLR( "schematic.grid_axes", LAYER_SCHEMATIC_GRID_AXES );
83  CLR( "schematic.hidden", LAYER_HIDDEN );
84  CLR( "schematic.junction", LAYER_JUNCTION );
85  CLR( "schematic.label_global", LAYER_GLOBLABEL );
86  CLR( "schematic.label_hier", LAYER_HIERLABEL );
87  CLR( "schematic.label_local", LAYER_LOCLABEL );
88  CLR( "schematic.no_connect", LAYER_NOCONNECT );
89  CLR( "schematic.note", LAYER_NOTES );
90  CLR( "schematic.pin", LAYER_PIN );
91  CLR( "schematic.pin_name", LAYER_PINNAM );
92  CLR( "schematic.pin_number", LAYER_PINNUM );
93  CLR( "schematic.reference", LAYER_REFERENCEPART );
94  // Macs look better with a lighter shadow
95 #ifdef __WXMAC__
96  CLR( "schematic.shadow", LAYER_SELECTION_SHADOWS );
97 #else
98  CLR( "schematic.shadow", LAYER_SELECTION_SHADOWS );
99 #endif
100  CLR( "schematic.sheet", LAYER_SHEET );
101  CLR( "schematic.sheet_background", LAYER_SHEET_BACKGROUND );
102  CLR( "schematic.sheet_filename", LAYER_SHEETFILENAME );
103  CLR( "schematic.sheet_fields", LAYER_SHEETFIELDS );
104  CLR( "schematic.sheet_label", LAYER_SHEETLABEL );
105  CLR( "schematic.sheet_name", LAYER_SHEETNAME );
106  CLR( "schematic.value", LAYER_VALUEPART );
107  CLR( "schematic.wire", LAYER_WIRE );
108  CLR( "schematic.worksheet", LAYER_SCHEMATIC_DRAWINGSHEET );
109 
110  CLR( "gerbview.axes", LAYER_GERBVIEW_AXES );
111  CLR( "gerbview.background", LAYER_GERBVIEW_BACKGROUND );
112  CLR( "gerbview.dcodes", LAYER_DCODES );
113  CLR( "gerbview.grid", LAYER_GERBVIEW_GRID );
114  CLR( "gerbview.negative_objects", LAYER_NEGATIVE_OBJECTS );
115  CLR( "gerbview.worksheet", LAYER_GERBVIEW_DRAWINGSHEET );
116 
117  for( int i = 0, id = GERBVIEW_LAYER_ID_START;
119  {
120  m_params.emplace_back( new COLOR_MAP_PARAM( "gerbview.layers." + std::to_string( i ), id,
121  default_palette[ i % default_palette.size() ],
122  &m_colors ) );
123  }
124 
125  CLR( "board.anchor", LAYER_ANCHOR );
126  CLR( "board.aux_items", LAYER_AUX_ITEMS );
127  CLR( "board.background", LAYER_PCB_BACKGROUND );
128  CLR( "board.cursor", LAYER_CURSOR );
129  CLR( "board.drc_error", LAYER_DRC_ERROR );
130  CLR( "board.drc_warning", LAYER_DRC_WARNING );
131  CLR( "board.drc_exclusion", LAYER_DRC_EXCLUSION );
132  CLR( "board.footprint_text_invisible", LAYER_MOD_TEXT_INVISIBLE );
133  CLR( "board.grid", LAYER_GRID );
134  CLR( "board.grid_axes", LAYER_GRID_AXES );
135  CLR( "board.no_connect", LAYER_NO_CONNECTS );
136  CLR( "board.pad_back", LAYER_PAD_BK );
137  CLR( "board.pad_front", LAYER_PAD_FR );
138  CLR( "board.pad_plated_hole", LAYER_PAD_PLATEDHOLES );
139  CLR( "board.pad_through_hole", LAYER_PADS_TH );
140  CLR( "board.plated_hole", LAYER_NON_PLATEDHOLES );
141  CLR( "board.ratsnest", LAYER_RATSNEST );
142  CLR( "board.via_blind_buried", LAYER_VIA_BBLIND );
143  CLR( "board.via_hole", LAYER_VIA_HOLES );
144  CLR( "board.via_micro", LAYER_VIA_MICROVIA );
145  CLR( "board.via_through", LAYER_VIA_THROUGH );
146  CLR( "board.worksheet", LAYER_DRAWINGSHEET );
147 
148  CLR( "board.copper.f", F_Cu );
149  CLR( "board.copper.in1", In1_Cu );
150  CLR( "board.copper.in2", In2_Cu );
151  CLR( "board.copper.in3", In3_Cu );
152  CLR( "board.copper.in4", In4_Cu );
153  CLR( "board.copper.in5", In5_Cu );
154  CLR( "board.copper.in6", In6_Cu );
155  CLR( "board.copper.in7", In7_Cu );
156  CLR( "board.copper.in8", In8_Cu );
157  CLR( "board.copper.in9", In9_Cu );
158  CLR( "board.copper.in10", In10_Cu );
159  CLR( "board.copper.in11", In11_Cu );
160  CLR( "board.copper.in12", In12_Cu );
161  CLR( "board.copper.in13", In13_Cu );
162  CLR( "board.copper.in14", In14_Cu );
163  CLR( "board.copper.in15", In15_Cu );
164  CLR( "board.copper.in16", In16_Cu );
165  CLR( "board.copper.in17", In17_Cu );
166  CLR( "board.copper.in18", In18_Cu );
167  CLR( "board.copper.in19", In19_Cu );
168  CLR( "board.copper.in20", In20_Cu );
169  CLR( "board.copper.in21", In21_Cu );
170  CLR( "board.copper.in22", In22_Cu );
171  CLR( "board.copper.in23", In23_Cu );
172  CLR( "board.copper.in24", In24_Cu );
173  CLR( "board.copper.in25", In25_Cu );
174  CLR( "board.copper.in26", In26_Cu );
175  CLR( "board.copper.in27", In27_Cu );
176  CLR( "board.copper.in28", In28_Cu );
177  CLR( "board.copper.in29", In29_Cu );
178  CLR( "board.copper.in30", In30_Cu );
179  CLR( "board.copper.b", B_Cu );
180 
181  CLR( "board.b_adhes", B_Adhes );
182  CLR( "board.f_adhes", F_Adhes );
183  CLR( "board.b_paste", B_Paste );
184  CLR( "board.f_paste", F_Paste );
185  CLR( "board.b_silks", B_SilkS );
186  CLR( "board.f_silks", F_SilkS );
187  CLR( "board.b_mask", B_Mask );
188  CLR( "board.f_mask", F_Mask );
189  CLR( "board.dwgs_user", Dwgs_User );
190  CLR( "board.cmts_user", Cmts_User );
191  CLR( "board.eco1_user", Eco1_User );
192  CLR( "board.eco2_user", Eco2_User );
193  CLR( "board.edge_cuts", Edge_Cuts );
194  CLR( "board.margin", Margin );
195  CLR( "board.b_crtyd", B_CrtYd );
196  CLR( "board.f_crtyd", F_CrtYd );
197  CLR( "board.b_fab", B_Fab );
198  CLR( "board.f_fab", F_Fab );
199  CLR( "board.user_1", User_1 );
200  CLR( "board.user_2", User_2 );
201  CLR( "board.user_3", User_3 );
202  CLR( "board.user_4", User_4 );
203  CLR( "board.user_5", User_5 );
204  CLR( "board.user_6", User_6 );
205  CLR( "board.user_7", User_7 );
206  CLR( "board.user_8", User_8 );
207  CLR( "board.user_9", User_9 );
208 
209  // Colors for 3D viewer, which are used as defaults unless overridden by the board
210  CLR( "3d_viewer.background_bottom", LAYER_3D_BACKGROUND_BOTTOM );
211  CLR( "3d_viewer.background_top", LAYER_3D_BACKGROUND_TOP );
212  CLR( "3d_viewer.board", LAYER_3D_BOARD );
213  CLR( "3d_viewer.copper", LAYER_3D_COPPER );
214  CLR( "3d_viewer.silkscreen_bottom", LAYER_3D_SILKSCREEN_BOTTOM );
215  CLR( "3d_viewer.silkscreen_top", LAYER_3D_SILKSCREEN_TOP );
216  CLR( "3d_viewer.soldermask", LAYER_3D_SOLDERMASK );
217  CLR( "3d_viewer.solderpaste", LAYER_3D_SOLDERPASTE );
218 
219  registerMigration( 0, 1, std::bind( &COLOR_SETTINGS::migrateSchema0to1, this ) );
220 
221  registerMigration( 1, 2,
222  [&]()
223  {
224  // Fix LAYER_VIA_HOLES color - before version 2, this setting had no effect
225  nlohmann::json::json_pointer ptr( "/board/via_hole");
226 
227  ( *m_internals )[ptr] = COLOR4D( 0.5, 0.4, 0, 0.8 ).ToWxString( wxC2S_CSS_SYNTAX );
228 
229  return true;
230  } );
231 }
232 
233 
235  JSON_SETTINGS( aOther.m_filename, SETTINGS_LOC::COLORS, colorsSchemaVersion )
236 {
237  initFromOther( aOther );
238 }
239 
240 
242 {
243  m_filename = aOther.m_filename;
244 
245  initFromOther( aOther );
246 
247  return *this;
248 }
249 
250 
252 {
253  m_displayName = aOther.m_displayName;
255  m_colors = aOther.m_colors;
257  m_writeFile = aOther.m_writeFile;
258 
259  // Ensure default colors are present
260  for( PARAM_BASE* param : aOther.m_params )
261  {
262  if( COLOR_MAP_PARAM* cmp = dynamic_cast<COLOR_MAP_PARAM*>( param ) )
263  m_defaultColors[cmp->GetKey()] = cmp->GetDefault();
264  }
265 }
266 
267 
268 bool COLOR_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
269 {
270  return false;
271 }
272 
273 
275 {
283  if( !m_manager )
284  {
285  wxLogTrace( traceSettings, "Error: COLOR_SETTINGS migration cannot run unmanaged!" );
286  return false;
287  }
288 
289  if( !Contains( "fpedit" ) )
290  {
291  wxLogTrace( traceSettings, "migrateSchema0to1: %s doesn't have fpedit settings; skipping.",
292  m_filename );
293  return true;
294  }
295 
296  wxString filename = m_filename + wxT( "_footprints" );
297 
298  COLOR_SETTINGS* fpsettings = m_manager->AddNewColorSettings( filename );
299 
300  // Start out with a clone
301  fpsettings->Set( "", At( "" ) );
302 
303  // Footprint editor now just looks at the "board" namespace
304  fpsettings->Set( "board", fpsettings->At( "fpedit" ) );
305 
306  fpsettings->Internals()->erase( "fpedit" );
307  fpsettings->Load();
308  fpsettings->SetName( fpsettings->GetName() + wxS( " " ) + _( "(Footprints)" ) );
309  m_manager->Save( fpsettings );
310 
311  // Now we can get rid of our own copy
312  m_internals->erase( "fpedit" );
313 
314  return true;
315 }
316 
317 
319 {
320  if( m_colors.count( aLayer ) )
321  return m_colors.at( aLayer );
322 
323  return COLOR4D::UNSPECIFIED;
324 }
325 
326 
328 {
329  if( !m_defaultColors.count( aLayer ) )
330  {
331  COLOR_MAP_PARAM* p = nullptr;
332 
333  for( PARAM_BASE* param : m_params )
334  {
335  COLOR_MAP_PARAM* cmp = dynamic_cast<COLOR_MAP_PARAM*>( param );
336 
337  if( cmp && cmp->GetKey() == aLayer )
338  p = cmp;
339  }
340 
341  if( p )
342  m_defaultColors[aLayer] = p->GetDefault();
343  else
344  m_defaultColors[aLayer] = COLOR4D::UNSPECIFIED;
345  }
346 
347  return m_defaultColors.at( aLayer );
348 }
349 
350 
351 void COLOR_SETTINGS::SetColor( int aLayer, COLOR4D aColor )
352 {
353  m_colors[ aLayer ] = aColor;
354 }
355 
356 
357 std::vector<COLOR_SETTINGS*> COLOR_SETTINGS::CreateBuiltinColorSettings()
358 {
359  COLOR_SETTINGS* defaultTheme = new COLOR_SETTINGS( wxT( "_builtin_default" ) );
360  defaultTheme->SetName( _( "KiCad Default" ) );
361  defaultTheme->m_writeFile = false;
362  defaultTheme->Load(); // We can just get the colors out of the param defaults for this one
363 
364  COLOR_SETTINGS* classicTheme = new COLOR_SETTINGS( wxT( "_builtin_classic" ) );
365  classicTheme->SetName( _( "KiCad Classic" ) );
366  classicTheme->m_writeFile = false;
367 
368  for( PARAM_BASE* param : classicTheme->m_params )
369  delete param;
370 
371  classicTheme->m_params.clear(); // Disable load/store
372 
373  for( const std::pair<int, COLOR4D> entry : s_classicTheme )
374  classicTheme->m_colors[entry.first] = entry.second;
375 
376  std::vector<COLOR_SETTINGS*> ret;
377 
378  ret.push_back( defaultTheme );
379  ret.push_back( classicTheme );
380 
381  return ret;
382 }
to draw blind/buried vias
show a marker on pads with no nets
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
JSON_SETTINGS_INTERNALS * Internals()
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
multilayer pads, usually with holes
to draw via holes (pad holes do not use this layer)
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
bool m_overrideSchItemColors
SETTINGS_LOC
Definition: json_settings.h:46
Definition: bitmap.cpp:64
static const std::map< int, COLOR4D > s_classicTheme
const int colorsSchemaVersion
! Update the schema version whenever a migration is required
wxString m_displayName
const wxString & GetName() const
COLOR_SETTINGS * AddNewColorSettings(const wxString &aFilename)
Registers a new color settings object with the given filename.
nlohmann::json & At(const std::string &aPath)
Wrappers for the underlying JSON API so that most consumers don't need json.hpp All of these function...
COLOR4D GetDefault() const
The color scheme directory (e.g. ~/.config/kicad/colors/)
int GetKey() const
wxString m_filename
The filename (not including path) of this settings file (inicode)
Auxiliary items (guides, rule, etc)
#define GERBER_DRAWLAYERS_COUNT
#define CSS_COLOR(r, g, b, a)
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
to draw usual through hole vias
#define CLR(x, y)
COLOR4D GetDefaultColor(int aLayer)
static std::vector< COLOR_SETTINGS * > CreateBuiltinColorSettings()
Constructs and returns a list of color settings objects based on the built-in color themes.
#define _(s)
void SetName(const wxString &aName)
std::unordered_map< int, COLOR4D > m_defaultColors
layer for drc markers which have been individually excluded
layer for drc markers with SEVERITY_WARNING
std::vector< COLOR4D > m_Palette
m_Pallete stores a list of colors that are used, in order, when a list of colors needs to be generate...
COLOR4D GetColor(int aLayer) const
std::unordered_map< int, COLOR4D > m_colors
Map of all layer colors.
smd pads, front layer
see class PGM_BASE
Board layer functions and definitions.
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
void initFromOther(const COLOR_SETTINGS &aOther)
COLOR_SETTINGS(wxString aFilename="user")
COLOR_SETTINGS & operator=(const COLOR_SETTINGS &aOther)
bool MigrateFromLegacy(wxConfigBase *aCfg) override
Migrates from wxConfig to JSON-based configuration.
Color settings are a bit different than most of the settings objects in that there can be more than o...
bool Contains(const std::string &aPath) const
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
drawingsheet frame and titleblock
SETTINGS_MANAGER * m_manager
A pointer to the settings manager managing this file (may be null)
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
layer for drc markers with SEVERITY_ERROR
void SetColor(int aLayer, COLOR4D aColor)
bool m_writeFile
Whether or not the backing store file should be written.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103