KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_project_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 <[email protected]>
5 * Copyright The 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 <functional>
22#include <lset.h>
23#include <lseq.h>
26
27using namespace std::placeholders;
28
29
31 std::vector<LAYER_PRESET>* aPresetList ) :
32 PARAM_LAMBDA<nlohmann::json>( aPath,
33 std::bind( &PARAM_LAYER_PRESET::presetsToJson, this ),
34 std::bind( &PARAM_LAYER_PRESET::jsonToPresets, this, _1 ),
35 {} ),
36 m_presets( aPresetList )
37{
38 wxASSERT( aPresetList );
39}
40
41
43{
44 nlohmann::json ret = nlohmann::json::array();
45
46 for( const LAYER_PRESET& preset : *m_presets )
47 {
48 nlohmann::json js = {
49 { "name", preset.name },
50 { "activeLayer", preset.activeLayer },
51 { "flipBoard", preset.flipBoard }
52 };
53
54 nlohmann::json layers = nlohmann::json::array();
55
56 for( PCB_LAYER_ID layer : preset.layers.Seq() )
57 layers.push_back( static_cast<int>( layer ) );
58
59 js["layers"] = layers;
60
61 nlohmann::json renderLayers = nlohmann::json::array();
62
63 for( GAL_LAYER_ID layer : preset.renderLayers.Seq() )
64 {
65 if( std::optional<VISIBILITY_LAYER> vl = VisibilityLayerFromRenderLayer( layer ) )
66 renderLayers.push_back( VisibilityLayerToString( *vl ) );
67 }
68
69 js["renderLayers"] = renderLayers;
70
71 ret.push_back( js );
72 }
73
74 return ret;
75}
76
77
78void PARAM_LAYER_PRESET::jsonToPresets( const nlohmann::json& aJson )
79{
80 if( aJson.empty() || !aJson.is_array() )
81 return;
82
83 m_presets->clear();
84
85 for( const nlohmann::json& preset : aJson )
86 {
87 if( preset.contains( "name" ) )
88 {
89 LAYER_PRESET p( preset.at( "name" ).get<wxString>() );
90
91 if( preset.contains( "flipBoard" ) && preset.at( "flipBoard" ).is_boolean() )
92 {
93 p.flipBoard = preset.at( "flipBoard" ).get<bool>();
94 }
95
96 if( preset.contains( "activeLayer" ) && preset.at( "activeLayer" ).is_number_integer() )
97 {
98 int active = preset.at( "activeLayer" ).get<int>();
99
100 if( active >= 0 && active < PCB_LAYER_ID_COUNT )
101 p.activeLayer = static_cast<PCB_LAYER_ID>( active );
102 }
103
104 if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
105 {
106 p.layers.reset();
107
108 for( const nlohmann::json& layer : preset.at( "layers" ) )
109 {
110 if( layer.is_number_integer() )
111 {
112 int layerNum = layer.get<int>();
113
114 if( layerNum >= 0 && layerNum < PCB_LAYER_ID_COUNT )
115 p.layers.set( layerNum );
116 }
117 }
118 }
119
120 if( preset.contains( "renderLayers" ) && preset.at( "renderLayers" ).is_array() )
121 {
122 p.renderLayers.reset();
123
124 for( const nlohmann::json& layer : preset.at( "renderLayers" ) )
125 {
126 if( layer.is_string() )
127 {
128 std::string vs = layer.get<std::string>();
129
130 if( std::optional<GAL_LAYER_ID> rl = RenderLayerFromVisbilityString( vs ) )
131 p.renderLayers.set( *rl );
132 }
133 }
134 }
135
136 m_presets->emplace_back( p );
137 }
138 }
139}
140
141
142void PARAM_LAYER_PRESET::MigrateToV9Layers( nlohmann::json& aJson )
143{
144 if( !aJson.is_object() || !aJson.contains( "layers" ) )
145 return;
146
147 std::vector<int> newLayers;
148
149 for( const nlohmann::json& layer : aJson.at( "layers" ) )
150 {
151 wxCHECK2( layer.is_number_integer(), continue );
152 newLayers.emplace_back( BoardLayerFromLegacyId( layer.get<int>() ) );
153 }
154
155 aJson["layers"] = newLayers;
156
157 if( aJson.contains( "activeLayer" ) )
158 aJson["activeLayer"] = BoardLayerFromLegacyId( aJson.at( "activeLayer" ).get<int>() );
159}
160
161
163{
164 static constexpr int V8_GAL_LAYER_ID_START = 125;
165
166 if( !aJson.is_object() || !aJson.contains( "renderLayers" ) )
167 return;
168
169 std::vector<std::string> newLayers;
170
171 for( const nlohmann::json& layer : aJson.at( "renderLayers" ) )
172 {
173 wxCHECK2( layer.is_number_integer(), continue );
174 GAL_LAYER_ID layerId = GAL_LAYER_ID_START + ( layer.get<int>() - V8_GAL_LAYER_ID_START );
175
176 if( std::optional<VISIBILITY_LAYER> vl = VisibilityLayerFromRenderLayer( layerId ) )
177 newLayers.emplace_back( VisibilityLayerToString( *vl ) );
178 }
179
180 aJson["renderLayers"] = newLayers;
181}
182
183
184PARAM_VIEWPORT::PARAM_VIEWPORT( const std::string& aPath, std::vector<VIEWPORT>* aViewportList ) :
185 PARAM_LAMBDA<nlohmann::json>( aPath,
186 std::bind( &PARAM_VIEWPORT::viewportsToJson, this ),
187 std::bind( &PARAM_VIEWPORT::jsonToViewports, this, _1 ),
188 {} ),
189 m_viewports( aViewportList )
190{
191 wxASSERT( aViewportList );
192}
193
194
196{
197 nlohmann::json ret = nlohmann::json::array();
198
199 for( const VIEWPORT& viewport : *m_viewports )
200 {
201 nlohmann::json js = {
202 { "name", viewport.name },
203 { "x", viewport.rect.GetX() },
204 { "y", viewport.rect.GetY() },
205 { "w", viewport.rect.GetWidth() },
206 { "h", viewport.rect.GetHeight() }
207 };
208
209 ret.push_back( js );
210 }
211
212 return ret;
213}
214
215
216void PARAM_VIEWPORT::jsonToViewports( const nlohmann::json& aJson )
217{
218 if( aJson.empty() || !aJson.is_array() )
219 return;
220
221 m_viewports->clear();
222
223 for( const nlohmann::json& viewport : aJson )
224 {
225 if( viewport.contains( "name" ) )
226 {
227 VIEWPORT v( viewport.at( "name" ).get<wxString>() );
228
229 if( viewport.contains( "x" ) )
230 v.rect.SetX( viewport.at( "x" ).get<double>() );
231
232 if( viewport.contains( "y" ) )
233 v.rect.SetY( viewport.at( "y" ).get<double>() );
234
235 if( viewport.contains( "w" ) )
236 v.rect.SetWidth( viewport.at( "w" ).get<double>() );
237
238 if( viewport.contains( "h" ) )
239 v.rect.SetHeight( viewport.at( "h" ).get<double>() );
240
241 m_viewports->emplace_back( v );
242 }
243 }
244}
245
246
247PARAM_VIEWPORT3D::PARAM_VIEWPORT3D( const std::string& aPath,
248 std::vector<VIEWPORT3D>* aViewportList ) :
249 PARAM_LAMBDA<nlohmann::json>( aPath,
250 std::bind( &PARAM_VIEWPORT3D::viewportsToJson, this ),
251 std::bind( &PARAM_VIEWPORT3D::jsonToViewports, this, _1 ),
252 {} ),
253 m_viewports( aViewportList )
254{
255 wxASSERT( aViewportList );
256}
257
258
260{
261 nlohmann::json ret = nlohmann::json::array();
262
263 for( const VIEWPORT3D& viewport : *m_viewports )
264 {
265 nlohmann::json js = {
266 { "name", viewport.name },
267 { "xx", viewport.matrix[0].x },
268 { "xy", viewport.matrix[0].y },
269 { "xz", viewport.matrix[0].z },
270 { "xw", viewport.matrix[0].w },
271 { "yx", viewport.matrix[1].x },
272 { "yy", viewport.matrix[1].y },
273 { "yz", viewport.matrix[1].z },
274 { "yw", viewport.matrix[1].w },
275 { "zx", viewport.matrix[2].x },
276 { "zy", viewport.matrix[2].y },
277 { "zz", viewport.matrix[2].z },
278 { "zw", viewport.matrix[2].w },
279 { "wx", viewport.matrix[3].x },
280 { "wy", viewport.matrix[3].y },
281 { "wz", viewport.matrix[3].z },
282 { "ww", viewport.matrix[3].w }
283 };
284
285 ret.push_back( js );
286 }
287
288 return ret;
289}
290
291
292void PARAM_VIEWPORT3D::jsonToViewports( const nlohmann::json& aJson )
293{
294 if( aJson.empty() || !aJson.is_array() )
295 return;
296
297 m_viewports->clear();
298
299 for( const nlohmann::json& viewport : aJson )
300 {
301 if( viewport.contains( "name" ) )
302 {
303 VIEWPORT3D v( viewport.at( "name" ).get<wxString>() );
304
305 if( viewport.contains( "xx" ) )
306 v.matrix[0].x = viewport.at( "xx" ).get<double>();
307
308 if( viewport.contains( "xy" ) )
309 v.matrix[0].y = viewport.at( "xy" ).get<double>();
310
311 if( viewport.contains( "xz" ) )
312 v.matrix[0].z = viewport.at( "xz" ).get<double>();
313
314 if( viewport.contains( "xw" ) )
315 v.matrix[0].w = viewport.at( "xw" ).get<double>();
316
317 if( viewport.contains( "yx" ) )
318 v.matrix[1].x = viewport.at( "yx" ).get<double>();
319
320 if( viewport.contains( "yy" ) )
321 v.matrix[1].y = viewport.at( "yy" ).get<double>();
322
323 if( viewport.contains( "yz" ) )
324 v.matrix[1].z = viewport.at( "yz" ).get<double>();
325
326 if( viewport.contains( "yw" ) )
327 v.matrix[1].w = viewport.at( "yw" ).get<double>();
328
329 if( viewport.contains( "zx" ) )
330 v.matrix[2].x = viewport.at( "zx" ).get<double>();
331
332 if( viewport.contains( "zy" ) )
333 v.matrix[2].y = viewport.at( "zy" ).get<double>();
334
335 if( viewport.contains( "zz" ) )
336 v.matrix[2].z = viewport.at( "zz" ).get<double>();
337
338 if( viewport.contains( "zw" ) )
339 v.matrix[2].w = viewport.at( "zw" ).get<double>();
340
341 if( viewport.contains( "wx" ) )
342 v.matrix[3].x = viewport.at( "wx" ).get<double>();
343
344 if( viewport.contains( "wy" ) )
345 v.matrix[3].y = viewport.at( "wy" ).get<double>();
346
347 if( viewport.contains( "wz" ) )
348 v.matrix[3].z = viewport.at( "wz" ).get<double>();
349
350 if( viewport.contains( "ww" ) )
351 v.matrix[3].w = viewport.at( "ww" ).get<double>();
352
353 m_viewports->emplace_back( v );
354 }
355 }
356}
357
358
359PARAM_LAYER_PAIRS::PARAM_LAYER_PAIRS( const std::string& aPath,
360 std::vector<LAYER_PAIR_INFO>& aLayerPairInfos ) :
361 PARAM_LAMBDA<nlohmann::json>( aPath,
362 std::bind( &PARAM_LAYER_PAIRS::layerPairsToJson, this ),
363 std::bind( &PARAM_LAYER_PAIRS::jsonToLayerPairs, this, _1 ),
364 {} ),
365 m_layerPairInfos( aLayerPairInfos )
366{
367}
368
369
371{
372 nlohmann::json ret = nlohmann::json::array();
373
374 for( const LAYER_PAIR_INFO& pairInfo : m_layerPairInfos )
375 {
376 const LAYER_PAIR& pair = pairInfo.GetLayerPair();
377 nlohmann::json js = {
378 { "topLayer", pair.GetLayerA() },
379 { "bottomLayer", pair.GetLayerB() },
380 { "enabled", pairInfo.IsEnabled() },
381 };
382
383 if( pairInfo.GetName().has_value() )
384 {
385 js["name"] = pairInfo.GetName().value();
386 }
387
388 ret.push_back( std::move( js ) );
389 }
390
391 return ret;
392}
393
394
395void PARAM_LAYER_PAIRS::jsonToLayerPairs( const nlohmann::json& aJson )
396{
397 if( aJson.empty() || !aJson.is_array() )
398 return;
399
400 m_layerPairInfos.clear();
401
402 for( const nlohmann::json& pairJson : aJson )
403 {
404 if( pairJson.contains( "topLayer" ) && pairJson.contains( "bottomLayer" ) )
405 {
406 LAYER_PAIR pair( pairJson.at( "topLayer" ).get<PCB_LAYER_ID>(),
407 pairJson.at( "bottomLayer" ).get<PCB_LAYER_ID>() );
408
409 bool enabled = true;
410 if( pairJson.contains( "enabled" ) )
411 enabled = pairJson.at( "enabled" ).get<bool>();
412
413 std::optional<wxString> name;
414 if( pairJson.contains( "name" ) )
415 name = pairJson.at( "name" ).get<wxString>();
416
417 m_layerPairInfos.emplace_back( LAYER_PAIR_INFO( pair, enabled, std::move( name ) ) );
418 }
419 }
420}
const char * name
Definition: DXF_plotter.cpp:59
BASE_SET & reset(size_t pos)
Definition: base_set.h:143
BASE_SET & set(size_t pos)
Definition: base_set.h:116
constexpr void SetHeight(size_type val)
Definition: box2.h:292
constexpr void SetWidth(size_type val)
Definition: box2.h:287
constexpr void SetX(coord_type val)
Definition: box2.h:277
constexpr void SetY(coord_type val)
Definition: box2.h:282
GAL_SET & set()
Definition: layer_ids.h:408
All information about a layer pair as stored in the layer pair store.
PCB_LAYER_ID GetLayerA() const
PCB_LAYER_ID GetLayerB() const
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:295
nlohmann::json layerPairsToJson()
void jsonToLayerPairs(const nlohmann::json &aJson)
std::vector< LAYER_PAIR_INFO > & m_layerPairInfos
PARAM_LAYER_PAIRS(const std::string &aPath, std::vector< LAYER_PAIR_INFO > &m_layerPairInfos)
static void MigrateToV9Layers(nlohmann::json &aJson)
static void MigrateToNamedRenderLayers(nlohmann::json &aJson)
nlohmann::json presetsToJson()
PARAM_LAYER_PRESET(const std::string &aPath, std::vector< LAYER_PRESET > *aPresetList)
std::vector< LAYER_PRESET > * m_presets
void jsonToPresets(const nlohmann::json &aJson)
void jsonToViewports(const nlohmann::json &aJson)
PARAM_VIEWPORT3D(const std::string &aPath, std::vector< VIEWPORT3D > *aViewportList)
nlohmann::json viewportsToJson()
std::vector< VIEWPORT3D > * m_viewports
std::vector< VIEWPORT > * m_viewports
PARAM_VIEWPORT(const std::string &aPath, std::vector< VIEWPORT > *aViewportList)
nlohmann::json viewportsToJson()
void jsonToViewports(const nlohmann::json &aJson)
nlohmann::json json
Definition: gerbview.cpp:47
PCB_LAYER_ID BoardLayerFromLegacyId(int aLegacyId)
Retrieve a layer ID from an integer converted from a legacy (pre-V9) enum value.
Definition: layer_id.cpp:215
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition: layer_ids.h:228
@ GAL_LAYER_ID_START
Definition: layer_ids.h:229
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:171
std::optional< VISIBILITY_LAYER > VisibilityLayerFromRenderLayer(GAL_LAYER_ID aLayerId)
std::string VisibilityLayerToString(VISIBILITY_LAYER aLayerId)
std::optional< GAL_LAYER_ID > RenderLayerFromVisbilityString(const std::string &aLayer)
STL namespace.
A saved set of layers that are visible.
GAL_SET renderLayers
Render layers (e.g. object types) that are visible.
bool flipBoard
True if the flip board is enabled.
LSET layers
Board layers that are visible.
PCB_LAYER_ID activeLayer
Optional layer to set active when this preset is loaded.