KiCad PCB EDA Suite
panel_eeschema_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 
21 #include <regex>
22 
23 #include <bitmaps.h>
24 #include <eeschema_settings.h>
27 #include <class_libentry.h>
28 #include <lib_polyline.h>
29 #include <page_info.h>
31 #include <pgm_base.h>
32 #include <sch_bus_entry.h>
33 #include <sch_junction.h>
34 #include <sch_line.h>
35 #include <sch_no_connect.h>
36 #include <sch_painter.h>
37 #include <sch_preview_panel.h>
38 #include <sch_text.h>
42 #include <title_block.h>
43 #include <view/view.h>
44 #include <ws_proxy_view_item.h>
45 #include <sch_base_frame.h>
46 #include <widgets/color_swatch.h>
47 
48 
50  wxWindow* aParent ) :
51  PANEL_COLOR_SETTINGS( aParent ),
52  m_frame( aFrame ),
53  m_preview( nullptr ),
54  m_page( nullptr ),
55  m_titleBlock( nullptr ),
56  m_ws( nullptr ),
57  m_previewItems()
58 {
59  m_colorNamespace = "schematic";
60 
61  SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
62 
63  mgr.ReloadColorSettings();
64 
65  COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
66  EESCHEMA_SETTINGS* app_settings = mgr.GetAppSettings<EESCHEMA_SETTINGS>();
67  COLOR_SETTINGS* current = mgr.GetColorSettings( app_settings->m_ColorTheme );
68 
69  createThemeList( app_settings->m_ColorTheme );
70 
71  m_optOverrideColors->SetValue( current->GetOverrideSchItemColors() );
72 
73  m_currentSettings = new COLOR_SETTINGS( *current );
74 
75  for( int id = SCH_LAYER_ID_START; id < SCH_LAYER_ID_END; id++ )
76  m_validLayers.push_back( id );
77 
79 
81 
83  options.ReadConfig( *common_settings, app_settings->m_Window, this );
84  options.m_forceDisplayCursor = false;
85 
86  auto type = static_cast<EDA_DRAW_PANEL_GAL::GAL_TYPE>( app_settings->m_Graphics.canvas_type );
87 
88  m_preview = new SCH_PREVIEW_PANEL( this, wxID_ANY, wxDefaultPosition, wxSize( -1, -1 ),
89  options, type );
90  m_preview->SetStealsFocus( false );
91  m_preview->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
92  m_preview->GetGAL()->SetAxesEnabled( false );
93 
94  m_colorsMainSizer->Add( 10, 0, 0, wxEXPAND, 5 );
95  m_colorsMainSizer->Add( m_preview, 1, wxALL | wxEXPAND, 5 );
96  m_colorsMainSizer->Add( 10, 0, 0, wxEXPAND, 5 );
97 
99  updatePreview();
100  zoomFitPreview();
101 }
102 
103 
105 {
106  delete m_page;
107  delete m_titleBlock;
108 
109  for( EDA_ITEM* item : m_previewItems )
110  delete item;
111 }
112 
113 
115 {
117 
118  if( !saveCurrentTheme( true ) )
119  return false;
120 
122 
123  SETTINGS_MANAGER& settingsMgr = Pgm().GetSettingsManager();
124  EESCHEMA_SETTINGS* app_settings = settingsMgr.GetAppSettings<EESCHEMA_SETTINGS>();
125  app_settings->m_ColorTheme = m_currentSettings->GetFilename();
126 
127  return true;
128 }
129 
130 
132 {
133  zoomFitPreview();
134  return true;
135 }
136 
137 
139 {
141 
142  for( SCH_LAYER_ID layer = SCH_LAYER_ID_START; layer < SCH_LAYER_ID_END; ++layer )
143  {
144  if( bgcolor == m_currentSettings->GetColor( layer )
145  && layer != LAYER_SCHEMATIC_BACKGROUND && layer != LAYER_SHEET_BACKGROUND )
146  {
147  wxString msg = _( "Some items have the same color as the background\n"
148  "and they will not be seen on the screen. Are you\n"
149  "sure you want to use these colors?" );
150 
151  if( wxMessageBox( msg, _( "Warning" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
152  return false;
153 
154  break;
155  }
156  }
157 
158  return true;
159 }
160 
161 
163 {
164  for( auto layer : m_validLayers )
165  {
167 
168  // Do not allow non-background layers to be completely white.
169  // This ensures the BW printing recognizes that the colors should be printed black.
171  && layer != LAYER_SHEET_BACKGROUND )
172  {
173  color.Darken( 0.01 );
174  }
175 
176  m_currentSettings->SetColor( layer, color );
177  }
178 
179  return PANEL_COLOR_SETTINGS::saveCurrentTheme( aValidate );
180 }
181 
182 
184 {
185  std::vector<SCH_LAYER_ID> layers;
186 
188  layers.push_back( i );
189 
190  std::sort( layers.begin(), layers.end(),
191  []( SCH_LAYER_ID a, SCH_LAYER_ID b )
192  {
193  return LayerName( a ) < LayerName( b );
194  } );
195 
196  for( int layer : layers )
197  createSwatch( layer, LayerName( layer ) );
198 }
199 
200 
202 {
203  updatePreview();
204 }
205 
206 
208 {
209  KIGFX::VIEW* view = m_preview->GetView();
210 
213 
214  m_page->SetHeightMils( 5000 );
215  m_page->SetWidthMils( 5500 );
216 
219  view->Add( m_ws );
220 
221  // NOTE: It would be nice to parse a schematic file here.
222  // This is created from the color_settings.sch file in demos folder
223 
224  auto addItem = [&]( EDA_ITEM* aItem )
225  {
226  view->Add( aItem );
227  m_previewItems.push_back( aItem );
228  };
229 
230  std::vector<std::pair<SCH_LAYER_ID, std::pair<wxPoint, wxPoint>>> lines = {
231  { LAYER_WIRE, { { 1950, 1500 }, { 2325, 1500 } } },
232  { LAYER_WIRE, { { 1950, 2600 }, { 2350, 2600 } } },
233  { LAYER_WIRE, { { 2150, 1700 }, { 2325, 1700 } } },
234  { LAYER_WIRE, { { 2150, 2000 }, { 2150, 1700 } } },
235  { LAYER_WIRE, { { 2925, 1600 }, { 3075, 1600 } } },
236  { LAYER_WIRE, { { 3075, 1600 }, { 3075, 2000 } } },
237  { LAYER_WIRE, { { 3075, 1600 }, { 3250, 1600 } } },
238  { LAYER_WIRE, { { 3075, 2000 }, { 2150, 2000 } } },
239  { LAYER_BUS, { { 1750, 1400 }, { 1850, 1400 } } },
240  { LAYER_BUS, { { 1850, 2500 }, { 1850, 1400 } } },
241  { LAYER_NOTES, { { 2350, 2125 }, { 2350, 2300 } } },
242  { LAYER_NOTES, { { 2350, 2125 }, { 2950, 2125 } } },
243  { LAYER_NOTES, { { 2950, 2125 }, { 2950, 2300 } } },
244  { LAYER_NOTES, { { 2950, 2300 }, { 2350, 2300 } } }
245  };
246 
247  for( const auto& line : lines )
248  {
249  SCH_LINE* wire = new SCH_LINE;
250  wire->SetLayer( line.first );
251  wire->SetStartPoint(
252  wxPoint( Mils2iu( line.second.first.x ), Mils2iu( line.second.first.y ) ) );
253  wire->SetEndPoint(
254  wxPoint( Mils2iu( line.second.second.x ), Mils2iu( line.second.second.y ) ) );
255  addItem( wire );
256  }
257 
258  auto nc = new SCH_NO_CONNECT;
259  nc->SetPosition( wxPoint( Mils2iu( 2525 ), Mils2iu( 1300 ) ) );
260  addItem( nc );
261 
262  auto e1 = new SCH_BUS_WIRE_ENTRY;
263  e1->SetPosition( wxPoint( Mils2iu( 1850 ), Mils2iu( 1400 ) ) );
264  addItem( e1 );
265 
266  auto e2 = new SCH_BUS_WIRE_ENTRY;
267  e2->SetPosition( wxPoint( Mils2iu( 1850 ), Mils2iu( 2500 ) ) );
268  addItem( e2 );
269 
270  auto t1 = new SCH_TEXT( wxPoint( Mils2iu( 2850 ), Mils2iu( 2250 ) ), wxT( "PLAIN TEXT" ) );
271  t1->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::LEFT );
272  addItem( t1 );
273 
274  auto t2 = new SCH_LABEL( wxPoint( Mils2iu( 1975 ), Mils2iu( 1500 ) ), wxT( "GLOBAL0" ) );
275  t2->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT );
276  t2->SetIsDangling( false );
277  addItem( t2 );
278 
279  auto t3 = new SCH_LABEL( wxPoint( Mils2iu( 1975 ), Mils2iu( 2600 ) ), wxT( "GLOBAL1" ) );
280  t3->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT );
281  t3->SetIsDangling( false );
282  addItem( t3 );
283 
284  auto t4 = new SCH_GLOBALLABEL( wxPoint( Mils2iu( 1750 ), Mils2iu( 1400 ) ), wxT( "GLOBAL[3..0]" ) );
285  t4->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::LEFT );
286  t4->SetIsDangling( false );
287  addItem( t4 );
288 
289  auto t5 = new SCH_HIERLABEL( wxPoint( Mils2iu( 3250 ), Mils2iu( 1600 ) ), wxT( "HIER_LABEL" ) );
290  t5->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT );
291  t5->SetIsDangling( false );
292  addItem( t5 );
293 
294  auto j = new SCH_JUNCTION( wxPoint( Mils2iu( 3075 ), Mils2iu( 1600 ) ) );
295  addItem( j );
296 
297  e2->SetBrightened();
298  t2->SetSelected();
299 
300  {
301  auto part = new LIB_PART( wxEmptyString );
302  wxPoint p( 2625, -1600 );
303 
304  part->SetShowPinNames( true );
305  part->SetShowPinNumbers( true );
306 
307  addItem( part );
308 
309  auto comp_body = new LIB_POLYLINE( part );
310 
311  comp_body->SetUnit( 0 );
312  comp_body->SetConvert( 0 );
313  comp_body->SetWidth( Mils2iu( 10 ) );
314  comp_body->SetFillMode( FILLED_WITH_BG_BODYCOLOR );
315  comp_body->AddPoint( wxPoint( Mils2iu( p.x - 200 ), Mils2iu( p.y + 200 ) ) );
316  comp_body->AddPoint( wxPoint( Mils2iu( p.x + 200 ), Mils2iu( p.y ) ) );
317  comp_body->AddPoint( wxPoint( Mils2iu( p.x - 200 ), Mils2iu( p.y - 200 ) ) );
318  comp_body->AddPoint( wxPoint( Mils2iu( p.x - 200 ), Mils2iu( p.y + 200 ) ) );
319 
320  addItem( comp_body );
321  }
322 
323  zoomFitPreview();
324 }
325 
326 
328 {
329  updatePreview();
330 }
331 
332 
334 {
336  updatePreview();
337 }
338 
339 
341 {
342  KIGFX::VIEW* view = m_preview->GetView();
343  auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
344  settings->LoadColors( m_currentSettings );
345 
346  m_preview->GetGAL()->SetClearColor( settings->GetBackgroundColor() );
347 
348  view->UpdateAllItems( KIGFX::COLOR );
349  auto rect = m_preview->GetScreenRect();
350  m_preview->Refresh( true, &rect );
351 }
352 
353 
355 {
356  auto view = m_preview->GetView();
357 
358  view->SetScale( 1.0 );
359  VECTOR2D screenSize = view->ToWorld( m_preview->GetClientSize(), false );
360 
361  VECTOR2I psize( m_page->GetWidthIU(), m_page->GetHeightIU() );
362  double scale = view->GetScale() / std::max( fabs( psize.x / screenSize.x ),
363  fabs( psize.y / screenSize.y ) );
364 
365  view->SetScale( scale / 1.02 );
366  view->SetCenter( m_ws->ViewBBox().Centre() );
368 }
369 
370 
371 void PANEL_EESCHEMA_COLOR_SETTINGS::OnSize( wxSizeEvent& aEvent )
372 {
373  zoomFitPreview();
374  aEvent.Skip();
375 }
376 
377 
379 {
381 
382  // If the theme is not overriding individual item colors then don't show them so that
383  // the user doesn't get seduced into thinking they'll have some effect.
386 
389 
390  m_colorsGridSizer->Layout();
391  m_colorsListWindow->Layout();
392 }
KIGFX::SCH_VIEW * GetView() const override
Function GetView() Returns a pointer to the VIEW instance used in the panel.
void SetClearColor(const COLOR4D &aColor)
void ForceRefresh()
Function ForceRefresh() Forces a redraw.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
virtual bool saveCurrentTheme(bool aValidate)
int color
Definition: DXF_plotter.cpp:61
std::map< int, wxStaticText * > m_labels
void UpdateAllItems(int aUpdateFlags)
Updates all items in the view according to the given flags.
Definition: view.cpp:1444
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
static const wxChar Custom[]
"User" defined page type
Definition: page_info.h:78
std::map< int, COLOR_SWATCH * > m_swatches
bool m_forceDisplayCursor
Force cursor display
Visibility flag has changed.
Definition: view_item.h:56
void OnSize(wxSizeEvent &aEvent) override
void SetColorLayer(int aLayerId)
Can be used to override which layer ID is used for worksheet item colors.
bool validateSave(bool aQuiet=false) override
Performs a pre-save validation of the current color theme.
TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout,...
Definition: title_block.h:40
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
void SetEndPoint(const wxPoint &aPosition)
Definition: sch_line.h:101
std::string m_colorNamespace
A namespace that will be passed to SETTINGS_MANAGER::SaveColorSettings.
bool saveCurrentTheme(bool aValidate) override
void onNewThemeSelected() override
Event fired when a new theme is selected that can be overridden in children.
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
void onColorChanged() override
Event fired when the user changes any color.
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
PANEL_EESCHEMA_COLOR_SETTINGS(SCH_BASE_FRAME *aFrame, wxWindow *aParent)
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
void createThemeList(const wxString &aCurrent)
Class LIB_PIN definition.
COLOR_SETTINGS * m_currentSettings
void SetStartPoint(const wxPoint &aPosition)
Definition: sch_line.h:98
void SetLayer(SCH_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Definition: sch_item.h:248
void SetOverrideSchItemColors(bool aFlag)
void OnBtnResetClicked(wxCommandEvent &event) override
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
Define a library symbol object.
KIGFX::GAL * GetGAL() const
Function GetGAL() Returns a pointer to the GAL instance used in the panel.
virtual KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
AppSettings * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
wxString LayerName(int aLayer)
Returns the string equivalent of a given layer.
Definition: layer_id.cpp:24
SCH_LAYER_ID
Eeschema drawing layers.
void SetAxesEnabled(bool aAxesEnabled)
Enables drawing the axes.
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:253
std::vector< int > m_validLayers
A list of layer IDs that are valid for the current color settings dialog.
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Function SetScale() Sets the scaling factor, zooming around a given anchor point.
Definition: view.cpp:578
void OnOverrideItemColorsClicked(wxCommandEvent &aEvent) override
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
COLOR4D GetColor(int aLayer) const
WINDOW_SETTINGS m_Window
Definition: app_settings.h:133
void ReloadColorSettings()
Re-scans the color themes directory, reloading any changes it finds.
const int scale
see class PGM_BASE
Board layer functions and definitions.
void OnBtnResetClicked(wxCommandEvent &aEvent) override
Vec Centre() const
Definition: box2.h:78
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:38
#define _(s)
Definition: 3d_actions.cpp:33
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:239
void ReadConfig(COMMON_SETTINGS &aCommonConfig, WINDOW_SETTINGS &aWindowConfig, wxWindow *aWindow)
Read application and common configs.
#define IU_PER_MILS
Definition: plotter.cpp:138
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
Definition: colors.h:49
Class for a wire to bus entry.
Color settings are a bit different than most of the settings objects in that there can be more than o...
std::string GetFilename() const
Definition: json_settings.h:57
bool GetOverrideSchItemColors() const
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
VIEW.
Definition: view.h:61
void Refresh(bool aEraseBackground, const wxRect *aRect) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
void createSwatch(int aLayer, const wxString &aName)
A shim class between EDA_DRAW_FRAME and several derived classes: LIB_EDIT_FRAME, LIB_VIEW_FRAME,...
void SetColor(int aLayer, COLOR4D aColor)
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:136
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40