Compare commits
326 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5526fba124 | |||
| cceafd5e7d | |||
| 4044ed65cd | |||
| a13dbf8cf4 | |||
| 2f42a85724 | |||
| 154c52defd | |||
| fc518c5584 | |||
| a7a7e963c9 | |||
| 46e6eb163b | |||
| 42429aff15 | |||
| f02c62971f | |||
| 47aba551d1 | |||
| c9295d6f60 | |||
| 6505b996c9 | |||
| ce134a1342 | |||
| 1f0530734e | |||
| 22df27111f | |||
| 68ab95ad43 | |||
| 32048d3b1e | |||
| 7498f1b1a6 | |||
| c55d2c092e | |||
| e13c414052 | |||
| ee49cf555a | |||
| 3aded5da4b | |||
| cbd55bc201 | |||
| 26674ceec3 | |||
| 71a6231bb8 | |||
| c4f9710f98 | |||
| 4c561b3193 | |||
| 6193652e89 | |||
| 8c980facb4 | |||
| 12782a163b | |||
| 73d43a985f | |||
| a9d1c87461 | |||
| 961588ef56 | |||
| 23955965d1 | |||
| 7882505426 | |||
| 707ec69916 | |||
| b788cb860a | |||
| 372f6dd9d6 | |||
| d4454bf3d2 | |||
| ae05479dff | |||
| 6727e4993c | |||
| 6de07ce92b | |||
| 348fe1c49d | |||
| 55e0780887 | |||
| 6c30e4f90b | |||
| fb92923f82 | |||
| c25264528c | |||
| e5e4d9b814 | |||
| a8d04d0079 | |||
| b345dac82b | |||
| dd2d8e1a62 | |||
| 227c74f2ee | |||
| 51557e5f66 | |||
| e35bd84c07 | |||
| 308c632f44 | |||
| dba149447c | |||
| 753a436183 | |||
| 9e9870580b | |||
| f8bf5d2c38 | |||
| af9cbdc4fb | |||
| 32ebb1f3a2 | |||
| 8650e5a063 | |||
| fe6fa68694 | |||
| 6b1a415281 | |||
| 328f37cc3f | |||
| 818d650ce2 | |||
| 648825127d | |||
| ad501536e8 | |||
| 13331d00bb | |||
| 2b2b7d2232 | |||
| a65fe79551 | |||
| 5b79ad7f6b | |||
| 184863db1a | |||
| 3ed4eece94 | |||
| 38c0e50f13 | |||
| 1215b0c304 | |||
| 14a05de36a | |||
| bb95659afb | |||
| 5edc846122 | |||
| a12bcbb6ea | |||
| aa69aa63be | |||
| c9e35a59dc | |||
| 785be9bd59 | |||
| 6cfd84993c | |||
| 56082b5d60 | |||
| e404e18c3d | |||
| 90df0c2d8b | |||
| ad26cec474 | |||
| 2982409887 | |||
| f357a55393 | |||
| 989e7c3779 | |||
| b3b4d65982 | |||
| 215f2d8320 | |||
| 4c6bbe21c0 | |||
| 55ffa472c6 | |||
| 410f3f0f7b | |||
| 01df75ed36 | |||
| be68120865 | |||
| 1c0a6fd14f | |||
| 60fca542ec | |||
| 072562eb1a | |||
| 68b86e6817 | |||
| 491b451519 | |||
| d7eea3cf7b | |||
| 4ba7cff25e | |||
| a4a3ee31e4 | |||
| 56345a4158 | |||
| 8c26f4f10e | |||
| ff02626f75 | |||
| d6a6337a96 | |||
| 42461e4a69 | |||
| ab51588005 | |||
| 3a4fdcd391 | |||
| 6d431d1670 | |||
| 398d6b4328 | |||
| f1d5093dfc | |||
| 67eff4e495 | |||
| c829773a44 | |||
| eec89791d8 | |||
| a4a27f0956 | |||
| 8458066468 | |||
| 33fad39cf4 | |||
| c2d3c9b292 | |||
| 37103c6e15 | |||
| 3b4111d3a2 | |||
| 906ef8bca7 | |||
| aab730abc1 | |||
| 91602ee7ba | |||
| ee513f7a8b | |||
| 5adc6ee2f4 | |||
| a4f71ae3ee | |||
| cc69f8b9ae | |||
| ec17012c81 | |||
| e93b05e413 | |||
| f82760f6e3 | |||
| 01a09e8a3f | |||
| fcc170f077 | |||
| 03d80dd8d8 | |||
| f91afe1f49 | |||
| 1bba0d96ad | |||
| a107722eac | |||
| d9bba779fd | |||
| 49dc16fcb0 | |||
| fc82d8d19c | |||
| ec061ebd2e | |||
| 65b509a225 | |||
| 097cef1819 | |||
| 8bf538f529 | |||
| 06fdb5e86c | |||
| b4831a17a0 | |||
| 32cef776da | |||
| ce314185fb | |||
| 9bd43071ae | |||
| bfe895bfd5 | |||
| dc3a3ec597 | |||
| 69e909dc76 | |||
| 446e7f3125 | |||
| cf66d47b74 | |||
| 11f3bbdbcb | |||
| 6028cb3ec2 | |||
| f7cdd9eaa7 | |||
| 3fadd20088 | |||
| 9db8765d52 | |||
| 5644e6d517 | |||
| 9be41e97f7 | |||
| 1c835fee75 | |||
| bae846c2cd | |||
| afe3d2c43e | |||
| e784b03f61 | |||
| 9a0a4b8671 | |||
| 6780cdb54c | |||
| c5771d8874 | |||
| 2cebea3b04 | |||
| dfb66e2fdb | |||
| 31a7048faf | |||
| 58a76a2617 | |||
| 4b137bbaea | |||
| 4a533bfb07 | |||
| 1e11916975 | |||
| df4435ed80 | |||
| ecf3697ad3 | |||
| aab7701c17 | |||
| 09da370512 | |||
| 0fca70a0bc | |||
| ff6bee400e | |||
| 2b99d3e2e6 | |||
| 30f1c400e2 | |||
| fe162b2f3c | |||
| 37f11379c3 | |||
| 9b253fbdd7 | |||
| 3068868f65 | |||
| 87de0ac806 | |||
| 8334a83aaa | |||
| 5cba809a1e | |||
| e23c2e30ee | |||
| 6cd3a802a7 | |||
| a3fff6ea10 | |||
| dd468a916e | |||
| e2b976594a | |||
| d8903534b7 | |||
| de1257abdf | |||
| 3d36d41ea7 | |||
| 2c74d46d79 | |||
| 7bee2cf842 | |||
| 6446e01483 | |||
| f5adac9369 | |||
| 312b75291b | |||
| c54b65fff7 | |||
| 766e48fb4f | |||
| 6ec1585c58 | |||
| c65d27dae1 | |||
| 82d572df80 | |||
| 32e9762230 | |||
| f987688b6f | |||
| 5544a315bd | |||
| 9d1344d707 | |||
| e0db6d013b | |||
| 13cbdda586 | |||
| a6d81d019f | |||
| fa10961d6c | |||
| a1a710dfed | |||
| 6efaa64908 | |||
| e918f820f5 | |||
| 806f9ea5fd | |||
| 9c4a88a129 | |||
| 956a633d4d | |||
| 63a03734e9 | |||
| 221f28eafc | |||
| d6406d1349 | |||
| 36b9c08793 | |||
| 6988e79714 | |||
| 147234ca68 | |||
| 71659be29b | |||
| b685378efa | |||
| 736044cd71 | |||
| de1a04d6b4 | |||
| 8149107e33 | |||
| 36eb0c75d4 | |||
| bc4fe1e05a | |||
| 0c083e560c | |||
| 4ff1fc2f1b | |||
| 141a6291c9 | |||
| 9043279301 | |||
| 4003fdfe98 | |||
| 3f060a6107 | |||
| ca284ebb4e | |||
| b446e794b8 | |||
| 8c162ecbca | |||
| d05fe64d41 | |||
| b2d3a602c5 | |||
| 2546534056 | |||
| 303c1bef7b | |||
| 9cbc1db2a1 | |||
| 2b8083920a | |||
| 69589840df | |||
| 558488f874 | |||
| 73f77658bb | |||
| 4d6bb9317b | |||
| 4aeb2c58fb | |||
| 0087959bf5 | |||
| efea324ee4 | |||
| 3c6cb7b5b9 | |||
| cae665cd76 | |||
| 547997e1a6 | |||
| 6ad924ea45 | |||
| 56d9d46a0b | |||
| b56ff24acd | |||
| cbeb6735e9 | |||
| 83b8bdf137 | |||
| a21bcb4903 | |||
| 4e064d5502 | |||
| 8e48445a5b | |||
| 6b1505438d | |||
| 7f6136454a | |||
| 548a33dace | |||
| 4ea36da4c3 | |||
| 37fe0eca73 | |||
| 3b45663866 | |||
| 238b5fedc8 | |||
| 8694c70237 | |||
| 84adec02a7 | |||
| d61d66505f | |||
| beb4bb9007 | |||
| b2c59f2359 | |||
| a417afac8e | |||
| 80e2153a14 | |||
| 7208e6baf6 | |||
| 8e81d9ec73 | |||
| a44c2d9a5c | |||
| 02688ce919 | |||
| 35e119c152 | |||
| e09f4d79c9 | |||
| 0e8afc8243 | |||
| a2ca66d05b | |||
| c32639d6b5 | |||
| f7572e254d | |||
| 817dba3a57 | |||
| daaee3f1b8 | |||
| ebef835852 | |||
| 6073a32833 | |||
| 1723346524 | |||
| 97982cd089 | |||
| 4e353c8366 | |||
| 772295c573 | |||
| 88c4913f65 | |||
| 1d80bd4043 | |||
| 3085ec0a5d | |||
| 5622a9e295 | |||
| 81585f7a83 | |||
| 7c953d11f7 | |||
| 5fa1d0eaeb | |||
| a0baef9d12 | |||
| b112ca3944 | |||
| d271a47375 | |||
| a9adc64f3e | |||
| 65f9264531 | |||
| d45fbaca96 | |||
| b007cb143d | |||
| 96bfa17469 | |||
| e7ea87f454 | |||
| e1c292e600 | |||
| 537a8cc652 | |||
| 62fa53ca96 | |||
| c1575392e6 |
@@ -24,6 +24,7 @@ common/template_fieldnames_lexer.h
|
||||
eeschema/schematic_keywords.*
|
||||
pcbnew/pcb_plot_params_keywords.cpp
|
||||
pcbnew/pcb_plot_params_lexer.h
|
||||
pcbnew/dialogs/panel_setup_rules_help_*.h
|
||||
Makefile
|
||||
CMakeUserPresets.json
|
||||
CMakeCache.txt
|
||||
|
||||
@@ -141,12 +141,13 @@ S3D_CACHE::~S3D_CACHE()
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
S3D_CACHE_ENTRY** aCachePtr, const EMBEDDED_FILES* aEmbeddedFiles )
|
||||
S3D_CACHE_ENTRY** aCachePtr,
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
|
||||
{
|
||||
if( aCachePtr )
|
||||
*aCachePtr = nullptr;
|
||||
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath, aEmbeddedFiles );
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath, aEmbeddedFilesStack );
|
||||
|
||||
if( full3Dpath.empty() )
|
||||
{
|
||||
@@ -212,9 +213,9 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePa
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
const EMBEDDED_FILES* aEmbeddedFiles )
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
|
||||
{
|
||||
return load( aModelFile, aBasePath, nullptr, aEmbeddedFiles );
|
||||
return load( aModelFile, aBasePath, nullptr, aEmbeddedFilesStack );
|
||||
}
|
||||
|
||||
|
||||
@@ -548,10 +549,10 @@ void S3D_CACHE::ClosePlugins()
|
||||
|
||||
|
||||
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath,
|
||||
const EMBEDDED_FILES* aEmbeddedFiles )
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
|
||||
{
|
||||
S3D_CACHE_ENTRY* cp = nullptr;
|
||||
SCENEGRAPH* sp = load( aModelFileName, aBasePath, &cp, aEmbeddedFiles );
|
||||
SCENEGRAPH* sp = load( aModelFileName, aBasePath, &cp, aEmbeddedFilesStack );
|
||||
|
||||
if( !sp )
|
||||
return nullptr;
|
||||
|
||||
@@ -95,11 +95,12 @@ public:
|
||||
*
|
||||
* @param aModelFile is the partial or full path to the model to be loaded.
|
||||
* @param aBasePath is the path to search for any relative files
|
||||
* @param aEmbeddedFiles is a pointer to the embedded files list.
|
||||
* @param aEmbeddedFilesStack is a list of pointers to the embedded files list. They will
|
||||
* be searched from the front of the list.
|
||||
* @return true if the model was successfully loaded, otherwise false.
|
||||
*/
|
||||
SCENEGRAPH* Load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
const EMBEDDED_FILES* aEmbeddedFiles );
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack );
|
||||
|
||||
FILENAME_RESOLVER* GetResolver() noexcept;
|
||||
|
||||
@@ -128,11 +129,12 @@ public:
|
||||
*
|
||||
* @param aModelFileName is the full path to the model to be loaded.
|
||||
* @param aBasePath is the path to search for any relative files.
|
||||
* @param aEmbeddedFiles is a pointer to the embedded files list.
|
||||
* @param aEmbeddedFilesStack is a stack of pointers to the embedded files lists. They will
|
||||
* be searched from the bottom of the stack.
|
||||
* @return is a pointer to the render data or NULL if not available.
|
||||
*/
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName, const wxString& aBasePath,
|
||||
const EMBEDDED_FILES* aEmbeddedFiles );
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack );
|
||||
|
||||
/**
|
||||
* Delete up old cache files in cache directory.
|
||||
@@ -174,7 +176,7 @@ private:
|
||||
// the real load function (can supply a cache entry pointer to member functions)
|
||||
SCENEGRAPH* load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
S3D_CACHE_ENTRY** aCachePtr = nullptr,
|
||||
const EMBEDDED_FILES* aEmbeddedFiles = nullptr );
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack = {} );
|
||||
|
||||
/// Cache entries.
|
||||
std::list< S3D_CACHE_ENTRY* > m_CacheList;
|
||||
|
||||
@@ -91,7 +91,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_IsPreviewer( false ),
|
||||
m_board( nullptr ),
|
||||
m_3dModelManager( nullptr ),
|
||||
m_colors( nullptr ),
|
||||
m_layerZcoordTop(),
|
||||
m_layerZcoordBottom()
|
||||
{
|
||||
@@ -137,13 +136,14 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
m_ECO1Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
|
||||
m_ECO2Color = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
|
||||
|
||||
for( int ii = 0; ii < 45; ++ii )
|
||||
m_UserDefinedLayerColor[ii] = SFVEC4F( 0.70, 0.10, 0.10, 1.0 );
|
||||
|
||||
m_platedPadsFront = nullptr;
|
||||
m_platedPadsBack = nullptr;
|
||||
m_offboardPadsFront = nullptr;
|
||||
m_offboardPadsBack = nullptr;
|
||||
|
||||
m_frontPlatedPadAndGraphicPolys = nullptr;
|
||||
m_backPlatedPadAndGraphicPolys = nullptr;
|
||||
m_frontPlatedCopperPolys = nullptr;
|
||||
m_backPlatedCopperPolys = nullptr;
|
||||
|
||||
@@ -229,11 +229,12 @@ void BOARD_ADAPTER::ReloadColorSettings() noexcept
|
||||
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
|
||||
COLOR_SETTINGS* colors = mgr.GetColorSettings( cfg ? cfg->m_ColorTheme : wxString( "" ) );
|
||||
|
||||
if( cfg )
|
||||
if( colors )
|
||||
{
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings( cfg->m_ColorTheme );
|
||||
GetBoardEditorCopperLayerColors( cfg );
|
||||
for( int layer = F_Cu; layer < PCB_LAYER_ID_COUNT; ++layer )
|
||||
m_BoardEditorColors[ layer ] = colors->GetColor( layer );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +263,15 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer,
|
||||
case Cmts_User: return aVisibilityFlags.test( LAYER_3D_USER_COMMENTS );
|
||||
case Eco1_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO1 );
|
||||
case Eco2_User: return aVisibilityFlags.test( LAYER_3D_USER_ECO2 );
|
||||
default: return m_board && m_board->IsLayerVisible( aLayer );
|
||||
default:
|
||||
{
|
||||
int layer3D = MapPCBLayerTo3DLayer( aLayer );
|
||||
|
||||
if( layer3D != UNDEFINED_LAYER )
|
||||
return aVisibilityFlags.test( layer3D );
|
||||
|
||||
return m_board && m_board->IsLayerVisible( aLayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,6 +577,9 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
m_UserCommentsColor = to_SFVEC4F( colors[ LAYER_3D_USER_COMMENTS ] );
|
||||
m_ECO1Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO1 ] );
|
||||
m_ECO2Color = to_SFVEC4F( colors[ LAYER_3D_USER_ECO2 ] );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
m_UserDefinedLayerColor[ layer - LAYER_3D_USER_1 ] = to_SFVEC4F( colors[ layer ] );
|
||||
}
|
||||
|
||||
|
||||
@@ -590,28 +602,15 @@ std::map<int, COLOR4D> BOARD_ADAPTER::GetDefaultColors() const
|
||||
colors[ LAYER_3D_USER_ECO1 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
colors[ LAYER_3D_USER_ECO2 ] = BOARD_ADAPTER::g_DefaultECOs;
|
||||
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings( wxEmptyString );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
colors[ layer ] = settings->GetColor( layer );
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::GetBoardEditorCopperLayerColors( PCBNEW_SETTINGS* aCfg )
|
||||
{
|
||||
m_BoardEditorColors.clear();
|
||||
|
||||
if( m_copperLayersCount <= 0 )
|
||||
return;
|
||||
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings( aCfg->m_ColorTheme );
|
||||
|
||||
LSET copperLayers = LSET::AllCuMask();
|
||||
|
||||
for( auto layer : LAYER_RANGE( F_Cu, B_Cu, m_copperLayersCount ) )
|
||||
{
|
||||
m_BoardEditorColors[ layer ] = settings->GetColor( layer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::map<int, COLOR4D> BOARD_ADAPTER::GetLayerColors() const
|
||||
{
|
||||
std::map<int, COLOR4D> colors;
|
||||
@@ -735,8 +734,13 @@ void BOARD_ADAPTER::SetLayerColors( const std::map<int, COLOR4D>& aColors )
|
||||
COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
|
||||
|
||||
for( const auto& [ layer, color ] : aColors )
|
||||
{
|
||||
settings->SetColor( layer, color );
|
||||
|
||||
if( layer >= LAYER_3D_USER_1 && layer <= LAYER_3D_USER_45 )
|
||||
m_UserDefinedLayerColor[ layer - LAYER_3D_USER_1 ] = GetColor( color );
|
||||
}
|
||||
|
||||
Pgm().GetSettingsManager().SaveColorSettings( settings, "3d_viewer" );
|
||||
}
|
||||
|
||||
@@ -757,6 +761,9 @@ void BOARD_ADAPTER::SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers )
|
||||
m_Cfg->m_Render.show_eco1 = aLayers.test( LAYER_3D_USER_ECO1 );
|
||||
m_Cfg->m_Render.show_eco2 = aLayers.test( LAYER_3D_USER_ECO2 );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
m_Cfg->m_Render.show_user[ layer - LAYER_3D_USER_1 ] = aLayers.test( layer );
|
||||
|
||||
m_Cfg->m_Render.show_footprints_normal = aLayers.test( LAYER_3D_TH_MODELS );
|
||||
m_Cfg->m_Render.show_footprints_insert = aLayers.test( LAYER_3D_SMD_MODELS );
|
||||
m_Cfg->m_Render.show_footprints_virtual = aLayers.test( LAYER_3D_VIRTUAL_MODELS );
|
||||
@@ -777,6 +784,46 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
{
|
||||
std::bitset<LAYER_3D_END> ret;
|
||||
|
||||
if( m_board && m_board->IsFootprintHolder() )
|
||||
{
|
||||
if( m_Cfg->m_Render.preview_show_board_body )
|
||||
{
|
||||
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
|
||||
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
|
||||
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
|
||||
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
|
||||
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
|
||||
}
|
||||
|
||||
ret.set( LAYER_3D_COPPER_TOP, true );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_TOP, true );
|
||||
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, true );
|
||||
ret.set( LAYER_3D_USER_COMMENTS, true );
|
||||
ret.set( LAYER_3D_USER_DRAWINGS, true );
|
||||
ret.set( LAYER_3D_USER_ECO1, true );
|
||||
ret.set( LAYER_3D_USER_ECO2, true );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
ret.set( layer, true );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, true );
|
||||
ret.set( LAYER_FP_VALUES, true );
|
||||
ret.set( LAYER_FP_TEXT, true );
|
||||
|
||||
ret.set( LAYER_3D_TH_MODELS, true );
|
||||
ret.set( LAYER_3D_SMD_MODELS, true );
|
||||
ret.set( LAYER_3D_VIRTUAL_MODELS, true );
|
||||
ret.set( LAYER_3D_MODELS_NOT_IN_POS, true );
|
||||
ret.set( LAYER_3D_MODELS_MARKED_DNP, true );
|
||||
|
||||
ret.set( LAYER_3D_BOUNDING_BOXES, m_Cfg->m_Render.show_model_bbox );
|
||||
ret.set( LAYER_3D_OFF_BOARD_SILK, m_Cfg->m_Render.show_off_board_silk );
|
||||
ret.set( LAYER_3D_AXES, m_Cfg->m_Render.show_axis );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
|
||||
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
|
||||
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
|
||||
@@ -791,6 +838,9 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
|
||||
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
ret.set( layer, m_Cfg->m_Render.show_user[ layer - LAYER_3D_USER_1 ] );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
|
||||
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
|
||||
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
|
||||
@@ -852,6 +902,9 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
|
||||
ret.set( LAYER_3D_USER_ECO1, layers.test( Eco1_User ) );
|
||||
ret.set( LAYER_3D_USER_ECO2, layers.test( Eco2_User ) );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
ret.set( layer, layers.test( Map3DLayerToPCBLayer( layer ) ) );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, plotParams.GetPlotReference() );
|
||||
ret.set( LAYER_FP_VALUES, plotParams.GetPlotValue() );
|
||||
ret.set( LAYER_FP_TEXT, plotParams.GetPlotFPText() );
|
||||
@@ -883,6 +936,9 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
|
||||
ret.set( LAYER_3D_USER_ECO1, false );
|
||||
ret.set( LAYER_3D_USER_ECO2, false );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
ret.set( layer, false );
|
||||
|
||||
ret.set( LAYER_FP_REFERENCES, true );
|
||||
ret.set( LAYER_FP_VALUES, true );
|
||||
ret.set( LAYER_FP_TEXT, true );
|
||||
@@ -901,6 +957,12 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetDefaultVisibleLayers() const
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::GetUseBoardEditorCopperLayerColors() const
|
||||
{
|
||||
return m_Cfg->m_Render.use_board_editor_copper_colors && !m_board->IsFootprintHolder();
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
{
|
||||
m_board_poly.RemoveAllContours();
|
||||
@@ -963,19 +1025,14 @@ float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
|
||||
}
|
||||
|
||||
|
||||
SFVEC4F BOARD_ADAPTER::GetLayerColor( PCB_LAYER_ID aLayerId ) const
|
||||
SFVEC4F BOARD_ADAPTER::GetLayerColor( int aLayerId ) const
|
||||
{
|
||||
if( aLayerId >= LAYER_3D_USER_1 && aLayerId <= LAYER_3D_USER_45 )
|
||||
aLayerId = Map3DLayerToPCBLayer( aLayerId );
|
||||
|
||||
wxASSERT( aLayerId < PCB_LAYER_ID_COUNT );
|
||||
|
||||
const COLOR4D color = m_colors->GetColor( aLayerId );
|
||||
|
||||
return SFVEC4F( color.r, color.g, color.b, color.a );
|
||||
}
|
||||
|
||||
|
||||
SFVEC4F BOARD_ADAPTER::GetItemColor( int aItemId ) const
|
||||
{
|
||||
return GetColor( m_colors->GetColor( aItemId ) );
|
||||
return GetColor( m_BoardEditorColors.at( aLayerId ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,11 +112,6 @@ public:
|
||||
*/
|
||||
std::map<int, COLOR4D> GetLayerColors() const;
|
||||
|
||||
/**
|
||||
* Build the copper color list used by the board editor, and store it in m_BoardEditorColors
|
||||
*/
|
||||
void GetBoardEditorCopperLayerColors( PCBNEW_SETTINGS* aCfg );
|
||||
|
||||
std::map<int, COLOR4D> GetDefaultColors() const;
|
||||
void SetLayerColors( const std::map<int, COLOR4D>& aColors );
|
||||
|
||||
@@ -124,6 +119,8 @@ public:
|
||||
std::bitset<LAYER_3D_END> GetDefaultVisibleLayers() const;
|
||||
void SetVisibleLayers( const std::bitset<LAYER_3D_END>& aLayers );
|
||||
|
||||
bool GetUseBoardEditorCopperLayerColors() const;
|
||||
|
||||
/**
|
||||
* Function to be called by the render when it need to reload the settings for the board.
|
||||
*
|
||||
@@ -210,15 +207,7 @@ public:
|
||||
* @param aLayerId the layer to get the color information.
|
||||
* @return the color in SFVEC3F format.
|
||||
*/
|
||||
SFVEC4F GetLayerColor( PCB_LAYER_ID aLayerId ) const;
|
||||
|
||||
/**
|
||||
* Get the technical color of a layer.
|
||||
*
|
||||
* @param aItemId the item id to get the color information.
|
||||
* @return the color in SFVEC3F format.
|
||||
*/
|
||||
SFVEC4F GetItemColor( int aItemId ) const;
|
||||
SFVEC4F GetLayerColor( int aLayerId ) const;
|
||||
|
||||
/**
|
||||
* @param[in] aColor is the color mapped.
|
||||
@@ -352,14 +341,14 @@ public:
|
||||
*/
|
||||
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
|
||||
|
||||
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys()
|
||||
const SHAPE_POLY_SET* GetFrontPlatedCopperPolys()
|
||||
{
|
||||
return m_frontPlatedPadAndGraphicPolys;
|
||||
return m_frontPlatedCopperPolys;
|
||||
}
|
||||
|
||||
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys()
|
||||
const SHAPE_POLY_SET* GetBackPlatedCopperPolys()
|
||||
{
|
||||
return m_backPlatedPadAndGraphicPolys;
|
||||
return m_backPlatedCopperPolys;
|
||||
}
|
||||
|
||||
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
|
||||
@@ -386,7 +375,7 @@ private:
|
||||
int aInflateValue );
|
||||
|
||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId,
|
||||
@@ -455,6 +444,7 @@ public:
|
||||
SFVEC4F m_UserCommentsColor;
|
||||
SFVEC4F m_ECO1Color;
|
||||
SFVEC4F m_ECO2Color;
|
||||
SFVEC4F m_UserDefinedLayerColor[45];
|
||||
|
||||
std::map<int, COLOR4D> m_ColorOverrides; ///< allows to override color scheme colors
|
||||
std::map<int, COLOR4D> m_BoardEditorColors; ///< list of colors used by the board editor
|
||||
@@ -462,7 +452,6 @@ public:
|
||||
private:
|
||||
BOARD* m_board;
|
||||
S3D_CACHE* m_3dModelManager;
|
||||
COLOR_SETTINGS* m_colors;
|
||||
|
||||
VECTOR2I m_boardPos; ///< Board center position in board internal units.
|
||||
VECTOR2I m_boardSize; ///< Board size in board internal units.
|
||||
@@ -472,8 +461,6 @@ private:
|
||||
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
|
||||
///< of items
|
||||
|
||||
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
|
||||
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
|
||||
SHAPE_POLY_SET* m_backPlatedCopperPolys;
|
||||
|
||||
|
||||
@@ -503,7 +503,7 @@ void BOARD_ADAPTER::createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstC
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
PCB_LAYER_ID aLayerId )
|
||||
{
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
@@ -527,24 +527,6 @@ void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aCo
|
||||
|
||||
switch( aLayerId )
|
||||
{
|
||||
case F_Cu:
|
||||
if( aSkipPlatedPads && pad->FlashLayer( F_Mask ) )
|
||||
continue;
|
||||
|
||||
if( aSkipNonPlatedPads && !pad->FlashLayer( F_Mask ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case B_Cu:
|
||||
if( aSkipPlatedPads && pad->FlashLayer( B_Mask ) )
|
||||
continue;
|
||||
|
||||
if( aSkipNonPlatedPads && !pad->FlashLayer( B_Mask ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case F_Mask:
|
||||
case B_Mask:
|
||||
margin.x += pad->GetSolderMaskExpansion( aLayerId );
|
||||
|
||||
@@ -183,8 +183,6 @@ void BOARD_ADAPTER::destroyLayers()
|
||||
|
||||
DELETE_AND_FREE_MAP( m_layers_poly );
|
||||
|
||||
DELETE_AND_FREE( m_frontPlatedPadAndGraphicPolys )
|
||||
DELETE_AND_FREE( m_backPlatedPadAndGraphicPolys )
|
||||
DELETE_AND_FREE( m_frontPlatedCopperPolys )
|
||||
DELETE_AND_FREE( m_backPlatedCopperPolys )
|
||||
|
||||
@@ -302,8 +300,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
if( cfg.DifferentiatePlatedCopper() )
|
||||
{
|
||||
m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
|
||||
m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
|
||||
m_frontPlatedCopperPolys = new SHAPE_POLY_SET;
|
||||
m_backPlatedCopperPolys = new SHAPE_POLY_SET;
|
||||
|
||||
@@ -334,11 +330,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
continue;
|
||||
|
||||
// Skip vias annulus when not flashed on this layer
|
||||
if( track->Type() == PCB_VIA_T
|
||||
&& !static_cast<const PCB_VIA*>( track )->FlashLayer( layer ) )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T && !static_cast<const PCB_VIA*>( track )->FlashLayer( layer ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add object item to layer container
|
||||
createTrackWithMargin( track, layerContainer, layer );
|
||||
@@ -394,8 +387,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
|
||||
// Add a hole for this layer
|
||||
layerHoleContainer->Add( new FILLED_CIRCLE_2D( via_center,
|
||||
hole_inner_radius + thickness,
|
||||
layerHoleContainer->Add( new FILLED_CIRCLE_2D( via_center, hole_inner_radius + thickness,
|
||||
*track ) );
|
||||
}
|
||||
else if( layer == layer_ids[0] ) // it only adds once the THT holes
|
||||
@@ -604,54 +596,38 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
}
|
||||
|
||||
// Add footprints PADs objects to containers
|
||||
// Add footprints copper items (pads, shapes and text) to containers
|
||||
for( PCB_LAYER_ID layer : layer_ids )
|
||||
{
|
||||
wxASSERT( m_layerMap.find( layer ) != m_layerMap.end() );
|
||||
|
||||
BVH_CONTAINER_2D *layerContainer = m_layerMap[layer];
|
||||
|
||||
// ADD PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
for( FOOTPRINT* fp : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, cfg.DifferentiatePlatedCopper(), false );
|
||||
addPads( fp, layerContainer, layer );
|
||||
addFootprintShapes( fp, layerContainer, layer, visibilityFlags );
|
||||
|
||||
// Micro-wave footprints may have items on copper layers
|
||||
addFootprintShapes( footprint, layerContainer, layer, visibilityFlags );
|
||||
}
|
||||
}
|
||||
|
||||
// Add footprints PADs poly contours (vertical outlines)
|
||||
if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
for( PCB_LAYER_ID layer : layer_ids )
|
||||
{
|
||||
wxASSERT( m_layers_poly.find( layer ) != m_layers_poly.end() );
|
||||
|
||||
SHAPE_POLY_SET *layerPoly = m_layers_poly[layer];
|
||||
|
||||
// Add pads to polygon list
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
// Add copper item to the plated copper polygon list if required
|
||||
if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) )
|
||||
{
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad has same shape as
|
||||
// its hole
|
||||
footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE,
|
||||
true, cfg.DifferentiatePlatedCopper(), false );
|
||||
SHAPE_POLY_SET* layerPoly = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys;
|
||||
|
||||
transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE );
|
||||
fp->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE, true );
|
||||
transformFPTextToPolySet( fp, layer, visibilityFlags, *layerPoly, maxError, ERROR_INSIDE );
|
||||
transformFPShapesToPolySet( fp, layer, *layerPoly, maxError, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
|
||||
if( cfg.DifferentiatePlatedCopper() )
|
||||
{
|
||||
// ADD PLATED PADS contours
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
// Add copper item to poly contours (vertical outlines) if required
|
||||
if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
footprint->TransformPadsToPolySet( *m_frontPlatedPadAndGraphicPolys, F_Cu, 0, maxError,
|
||||
ERROR_INSIDE, true, false, true );
|
||||
wxASSERT( m_layers_poly.contains( layer ) );
|
||||
|
||||
footprint->TransformPadsToPolySet( *m_backPlatedPadAndGraphicPolys, B_Cu, 0, maxError,
|
||||
ERROR_INSIDE, true, false, true );
|
||||
SHAPE_POLY_SET* layerPoly = m_layers_poly[layer];
|
||||
|
||||
fp->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE, true );
|
||||
transformFPTextToPolySet( fp, layer, visibilityFlags, *layerPoly, maxError, ERROR_INSIDE );
|
||||
transformFPShapesToPolySet( fp, layer, *layerPoly, maxError, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -696,59 +672,42 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
break;
|
||||
|
||||
default:
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
|
||||
item->Type() );
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), item->Type() );
|
||||
break;
|
||||
}
|
||||
|
||||
// add also this shape to the plated copper polygon list if required
|
||||
if( cfg.DifferentiatePlatedCopper() )
|
||||
// Add copper item to the plated copper polygon list if required
|
||||
if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) )
|
||||
{
|
||||
SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys;
|
||||
|
||||
// Note: for TEXT and TEXTBOX, TransformShapeToPolygon returns the bounding
|
||||
// box shape, not the exact text shape. So it is not used for these items
|
||||
if( layer == F_Cu || layer == B_Cu )
|
||||
if( item->Type() == PCB_TEXTBOX_T )
|
||||
{
|
||||
SHAPE_POLY_SET* platedCopperPolys = layer == F_Cu
|
||||
? m_frontPlatedCopperPolys
|
||||
: m_backPlatedCopperPolys;
|
||||
|
||||
if( item->Type() == PCB_TEXTBOX_T )
|
||||
{
|
||||
PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item );
|
||||
text_box->TransformTextToPolySet( *platedCopperPolys,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
// Add box outlines
|
||||
text_box->PCB_SHAPE::TransformShapeToPolygon( *platedCopperPolys, layer,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
else if( item->Type() == PCB_TEXT_T )
|
||||
{
|
||||
static_cast<PCB_TEXT*>( item )->TransformTextToPolySet(
|
||||
*platedCopperPolys,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
else
|
||||
item->TransformShapeToPolygon( *platedCopperPolys, layer,
|
||||
0, maxError, ERROR_INSIDE );
|
||||
PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item );
|
||||
text_box->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE );
|
||||
// Add box outlines
|
||||
text_box->PCB_SHAPE::TransformShapeToPolygon( *copperPolys, layer, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
else if( item->Type() == PCB_TEXT_T )
|
||||
{
|
||||
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
|
||||
text->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
else
|
||||
{
|
||||
item->TransformShapeToPolygon( *copperPolys, layer, 0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add graphic item on copper layers to poly contours (vertical outlines)
|
||||
if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
for( PCB_LAYER_ID layer : layer_ids )
|
||||
{
|
||||
wxASSERT( m_layers_poly.find( layer ) != m_layers_poly.end() );
|
||||
|
||||
SHAPE_POLY_SET *layerPoly = m_layers_poly[layer];
|
||||
|
||||
// Add graphic items on copper layers (texts and other )
|
||||
for( BOARD_ITEM* item : m_board->Drawings() )
|
||||
// Add copper item to poly contours (vertical outlines) if required
|
||||
if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
if( !item->IsOnLayer( layer ) )
|
||||
continue;
|
||||
wxASSERT( m_layers_poly.contains( layer ) );
|
||||
|
||||
SHAPE_POLY_SET *layerPoly = m_layers_poly[layer];
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
@@ -768,17 +727,51 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
|
||||
|
||||
if( textbox->IsBorderEnabled() )
|
||||
{
|
||||
textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0,
|
||||
maxError, ERROR_INSIDE );
|
||||
}
|
||||
|
||||
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
{
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
|
||||
|
||||
for( PCB_TABLECELL* cell : table->GetCells() )
|
||||
cell->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
|
||||
table->DrawBorders(
|
||||
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB,
|
||||
const STROKE_PARAMS& stroke )
|
||||
{
|
||||
SHAPE_SEGMENT seg( ptA, ptB, stroke.GetWidth() );
|
||||
seg.TransformToPolygon( *layerPoly, maxError, ERROR_INSIDE );
|
||||
} );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_RADIAL_T:
|
||||
case PCB_DIM_ORTHOGONAL_T:
|
||||
case PCB_DIM_LEADER_T:
|
||||
{
|
||||
PCB_DIMENSION_BASE* dimension = static_cast<PCB_DIMENSION_BASE*>( item );
|
||||
|
||||
dimension->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
|
||||
for( const std::shared_ptr<SHAPE>& shape : dimension->GetShapes() )
|
||||
shape->TransformToPolygon( *layerPoly, maxError, ERROR_INSIDE );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
|
||||
item->Type() );
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), item->Type() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -800,15 +793,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
zones.emplace_back( std::make_pair( zone, layer ) );
|
||||
layer_lock.emplace( layer, std::make_unique<std::mutex>() );
|
||||
|
||||
if( cfg.DifferentiatePlatedCopper() && layer == F_Cu )
|
||||
if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) )
|
||||
{
|
||||
zone->TransformShapeToPolygon( *m_frontPlatedCopperPolys, F_Cu, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
else if( cfg.DifferentiatePlatedCopper() && layer == B_Cu )
|
||||
{
|
||||
zone->TransformShapeToPolygon( *m_backPlatedCopperPolys, B_Cu, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys;
|
||||
|
||||
zone->TransformShapeToPolygon( *copperPolys, layer, 0, maxError, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -890,7 +879,52 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User
|
||||
Eco2_User,
|
||||
User_1,
|
||||
User_2,
|
||||
User_3,
|
||||
User_4,
|
||||
User_5,
|
||||
User_6,
|
||||
User_7,
|
||||
User_8,
|
||||
User_9,
|
||||
User_10,
|
||||
User_11,
|
||||
User_12,
|
||||
User_13,
|
||||
User_14,
|
||||
User_15,
|
||||
User_16,
|
||||
User_17,
|
||||
User_18,
|
||||
User_19,
|
||||
User_20,
|
||||
User_21,
|
||||
User_22,
|
||||
User_23,
|
||||
User_24,
|
||||
User_25,
|
||||
User_26,
|
||||
User_27,
|
||||
User_28,
|
||||
User_29,
|
||||
User_30,
|
||||
User_31,
|
||||
User_32,
|
||||
User_33,
|
||||
User_34,
|
||||
User_35,
|
||||
User_36,
|
||||
User_37,
|
||||
User_38,
|
||||
User_39,
|
||||
User_40,
|
||||
User_41,
|
||||
User_42,
|
||||
User_43,
|
||||
User_44,
|
||||
User_45,
|
||||
} );
|
||||
|
||||
std::bitset<LAYER_3D_END> enabledFlags = visibilityFlags;
|
||||
@@ -991,7 +1025,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
else
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, false, false );
|
||||
addPads( footprint, layerContainer, layer );
|
||||
}
|
||||
|
||||
addFootprintShapes( footprint, layerContainer, layer, visibilityFlags );
|
||||
@@ -1037,13 +1071,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
|
||||
|
||||
if( textbox->IsBorderEnabled() )
|
||||
{
|
||||
textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0,
|
||||
maxError, ERROR_INSIDE );
|
||||
}
|
||||
|
||||
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
{
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
|
||||
|
||||
for( PCB_TABLECELL* cell : table->GetCells() )
|
||||
cell->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
|
||||
table->DrawBorders(
|
||||
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB,
|
||||
const STROKE_PARAMS& stroke )
|
||||
{
|
||||
SHAPE_SEGMENT seg( ptA, ptB, stroke.GetWidth() );
|
||||
seg.TransformToPolygon( *layerPoly, maxError, ERROR_INSIDE );
|
||||
} );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -1057,12 +1111,23 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
for( PCB_TRACK* track : m_board->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T
|
||||
&& static_cast<const PCB_VIA*>( track )->FlashLayer( layer )
|
||||
&& !static_cast<const PCB_VIA*>( track )->IsTented( layer ) )
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError,
|
||||
ERROR_INSIDE );
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
|
||||
|
||||
if( via->FlashLayer( layer ) && !via->IsTented( layer ) )
|
||||
{
|
||||
track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( track->HasSolderMask() )
|
||||
{
|
||||
track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1121,9 +1186,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
if( !footprint->GetBoundingBox().Intersects( boardBBox ) )
|
||||
{
|
||||
if( footprint->IsFlipped() )
|
||||
addPads( footprint, m_offboardPadsBack, B_Cu, false, false );
|
||||
addPads( footprint, m_offboardPadsBack, B_Cu );
|
||||
else
|
||||
addPads( footprint, m_offboardPadsFront, F_Cu, false, false );
|
||||
addPads( footprint, m_offboardPadsFront, F_Cu );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,41 +1218,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
}
|
||||
|
||||
// Subtract plated copper from unplated copper
|
||||
bool hasF_Cu = false;
|
||||
bool hasB_Cu = false;
|
||||
|
||||
if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys );
|
||||
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys );
|
||||
hasF_Cu = true;
|
||||
}
|
||||
|
||||
if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() )
|
||||
{
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys );
|
||||
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys );
|
||||
hasB_Cu = true;
|
||||
}
|
||||
|
||||
// Add plated graphic items to build vertical walls
|
||||
if( hasF_Cu && m_frontPlatedCopperPolys->OutlineCount() )
|
||||
m_frontPlatedPadAndGraphicPolys->Append( *m_frontPlatedCopperPolys );
|
||||
|
||||
if( hasB_Cu && m_backPlatedCopperPolys->OutlineCount() )
|
||||
m_backPlatedPadAndGraphicPolys->Append( *m_backPlatedCopperPolys );
|
||||
|
||||
m_frontPlatedPadAndGraphicPolys->Simplify();
|
||||
m_backPlatedPadAndGraphicPolys->Simplify();
|
||||
m_frontPlatedCopperPolys->Simplify();
|
||||
m_backPlatedCopperPolys->Simplify();
|
||||
|
||||
// ADD PLATED PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
|
||||
}
|
||||
|
||||
// ADD PLATED COPPER
|
||||
ConvertPolygonToTriangles( *m_frontPlatedCopperPolys, *m_platedPadsFront, m_biuTo3Dunits,
|
||||
|
||||
@@ -451,7 +451,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't attend to ray trace if OpenGL doesn't support it.
|
||||
// Don't attempt to ray trace if OpenGL doesn't support it.
|
||||
if( !m_opengl_supports_raytracing )
|
||||
{
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
@@ -459,7 +459,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
|
||||
}
|
||||
|
||||
// Check if a raytacing was requested and need to switch to raytracing mode
|
||||
// Check if a raytracing was requested and need to switch to raytracing mode
|
||||
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
|
||||
{
|
||||
const bool was_camera_changed = m_camera.ParametersChanged();
|
||||
|
||||
@@ -157,7 +157,7 @@ void EDA_3D_MODEL_VIEWER::Set3DModel( const wxString& aModelPathName)
|
||||
|
||||
if( m_cacheManager )
|
||||
{
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString, nullptr );
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString, {} );
|
||||
|
||||
if( model )
|
||||
Set3DModel( (const S3DMODEL &)*model );
|
||||
|
||||
@@ -607,14 +607,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.DifferentiatePlatedCopper() )
|
||||
{
|
||||
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys =
|
||||
m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
|
||||
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys =
|
||||
m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
|
||||
const SHAPE_POLY_SET* frontPlatedCopperPolys = m_boardAdapter.GetFrontPlatedCopperPolys();
|
||||
const SHAPE_POLY_SET* backPlatedCopperPolys = m_boardAdapter.GetBackPlatedCopperPolys();
|
||||
|
||||
if( frontPlatedPadAndGraphicPolys )
|
||||
if( frontPlatedCopperPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
SHAPE_POLY_SET poly = frontPlatedCopperPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
@@ -627,9 +625,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
|
||||
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
|
||||
}
|
||||
|
||||
if( backPlatedPadAndGraphicPolys )
|
||||
if( backPlatedCopperPolys )
|
||||
{
|
||||
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
|
||||
SHAPE_POLY_SET poly = backPlatedCopperPolys->CloneDropTriangulation();
|
||||
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
|
||||
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
|
||||
@@ -928,8 +926,8 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
// Go for all footprints
|
||||
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
|
||||
{
|
||||
wxString libraryName = footprint->GetFPID().GetLibNickname();
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
wxString libraryName = footprint->GetFPID().GetLibNickname();
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
|
||||
if( m_boardAdapter.GetBoard()->GetProject() )
|
||||
{
|
||||
@@ -967,10 +965,13 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
||||
if( m_3dModelMap.find( fp_model.m_Filename ) == m_3dModelMap.end() )
|
||||
{
|
||||
// It is not present, try get it from cache
|
||||
const S3DMODEL* modelPtr =
|
||||
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename,
|
||||
footprintBasePath,
|
||||
footprint );
|
||||
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
|
||||
embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
|
||||
embeddedFilesStack.push_back( m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
|
||||
|
||||
const S3DMODEL* modelPtr = m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename,
|
||||
footprintBasePath,
|
||||
embeddedFilesStack );
|
||||
|
||||
// only add it if the return is not NULL
|
||||
if( modelPtr )
|
||||
|
||||
@@ -271,9 +271,7 @@ void RENDER_3D_OPENGL::setupMaterials()
|
||||
|
||||
void RENDER_3D_OPENGL::setLayerMaterial( PCB_LAYER_ID aLayerID )
|
||||
{
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS& cfg = m_boardAdapter.m_Cfg->m_Render;
|
||||
|
||||
if( cfg.use_board_editor_copper_colors && IsCopperLayer( aLayerID ) )
|
||||
if( m_boardAdapter.GetUseBoardEditorCopperLayerColors() && IsCopperLayer( aLayerID ) )
|
||||
{
|
||||
COLOR4D copper_color = m_boardAdapter.m_BoardEditorColors[aLayerID];
|
||||
m_materials.m_Copper.m_Diffuse = SFVEC3F( copper_color.r, copper_color.g,
|
||||
@@ -362,10 +360,34 @@ void RENDER_3D_OPENGL::setLayerMaterial( PCB_LAYER_ID aLayerID )
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
int layer3D = MapPCBLayerTo3DLayer( aLayerID );
|
||||
|
||||
// Note: MUST do this in LAYER_3D space; User_1..User_45 are NOT contiguous
|
||||
if( layer3D >= LAYER_3D_USER_1 && layer3D <= LAYER_3D_USER_45 )
|
||||
{
|
||||
int user_idx = layer3D - LAYER_3D_USER_1;
|
||||
|
||||
m_materials.m_Plastic.m_Diffuse = m_boardAdapter.m_UserDefinedLayerColor[ user_idx ];
|
||||
m_materials.m_Plastic.m_Ambient = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.05f,
|
||||
m_materials.m_Plastic.m_Diffuse.g * 0.05f,
|
||||
m_materials.m_Plastic.m_Diffuse.b * 0.05f );
|
||||
|
||||
m_materials.m_Plastic.m_Specular = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.7f,
|
||||
m_materials.m_Plastic.m_Diffuse.g * 0.7f,
|
||||
m_materials.m_Plastic.m_Diffuse.b * 0.7f );
|
||||
|
||||
m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
|
||||
m_materials.m_Plastic.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
|
||||
OglSetMaterial( m_materials.m_Plastic, 1.0f );
|
||||
break;
|
||||
}
|
||||
|
||||
m_materials.m_Copper.m_Diffuse = m_boardAdapter.m_CopperColor;
|
||||
OglSetMaterial( m_materials.m_Copper, 1.0f );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -632,7 +632,15 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
|
||||
break;
|
||||
|
||||
default:
|
||||
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
{
|
||||
int layer3D = MapPCBLayerTo3DLayer( layer_id );
|
||||
|
||||
// Note: MUST do this in LAYER_3D space; User_1..User_45 are NOT contiguous
|
||||
if( layer3D >= LAYER_3D_USER_1 && layer3D <= LAYER_3D_USER_45 )
|
||||
{
|
||||
layerColor = m_boardAdapter.m_UserDefinedLayerColor[ layer3D - LAYER_3D_USER_1 ];
|
||||
}
|
||||
else if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
|
||||
{
|
||||
layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
|
||||
materialLayer = &m_materials.m_NonPlatedCopper;
|
||||
@@ -645,6 +653,7 @@ void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarn
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
createItemsFromContainer( container2d, layer_id, materialLayer, layerColor, 0.0f );
|
||||
} // for each layer on map
|
||||
@@ -1282,8 +1291,12 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer,
|
||||
continue;
|
||||
|
||||
// get it from cache
|
||||
const S3DMODEL* modelPtr =
|
||||
cacheMgr->GetModel( model.m_Filename, footprintBasePath, fp );
|
||||
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
|
||||
embeddedFilesStack.push_back( fp->GetEmbeddedFiles() );
|
||||
embeddedFilesStack.push_back( m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
|
||||
|
||||
const S3DMODEL* modelPtr = cacheMgr->GetModel( model.m_Filename, footprintBasePath,
|
||||
embeddedFilesStack );
|
||||
|
||||
// only add it if the return is not NULL.
|
||||
if( modelPtr )
|
||||
|
||||
@@ -274,10 +274,12 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR
|
||||
}
|
||||
};
|
||||
|
||||
for( size_t i = 0; i < tp.get_thread_count() + 1; ++i )
|
||||
tp.push_task( processBlocks );
|
||||
BS::multi_future<void> futures;
|
||||
|
||||
tp.wait_for_tasks();
|
||||
for( size_t i = 0; i < tp.get_thread_count(); ++i )
|
||||
futures.push_back( tp.submit( processBlocks ) );
|
||||
|
||||
futures.wait();
|
||||
|
||||
m_blockRenderProgressCount += numBlocksRendered;
|
||||
|
||||
|
||||
@@ -482,6 +482,8 @@ void EDA_3D_VIEWER_FRAME::Process_Special_Functions( wxCommandEvent &event )
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
EDA_3D_VIEWER_SETTINGS* cfg = mgr.GetAppSettings<EDA_3D_VIEWER_SETTINGS>( "3d_viewer" );
|
||||
|
||||
m_boardAdapter.SetLayerColors( m_boardAdapter.GetDefaultColors() );
|
||||
|
||||
cfg->ResetToDefaults();
|
||||
LoadSettings( cfg );
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <3d_enums.h>
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <settings/parameters.h>
|
||||
@@ -353,6 +354,13 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
&m_Render.show_eco1, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_eco2",
|
||||
&m_Render.show_eco2, true ) );
|
||||
|
||||
for( int layer = 0; layer < 45; ++layer )
|
||||
{
|
||||
m_params.emplace_back( new PARAM<bool>( fmt::format( "render.show_user{}", layer + 1 ),
|
||||
&m_Render.show_user[layer], false ) );
|
||||
}
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_insert",
|
||||
&m_Render.show_footprints_insert, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.show_footprints_normal",
|
||||
@@ -393,6 +401,8 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
|
||||
&m_Render.differentiate_plated_copper, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.use_board_editor_copper_colors",
|
||||
&m_Render.use_board_editor_copper_colors, false ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "render.preview_show_board_body",
|
||||
&m_Render.preview_show_board_body, true ) );
|
||||
m_params.emplace_back( new PARAM<bool>( "camera.animation_enabled",
|
||||
&m_Camera.animation_enabled, true ) );
|
||||
m_params.emplace_back( new PARAM<int>( "camera.moving_speed_multiplier",
|
||||
|
||||
@@ -132,6 +132,7 @@ public:
|
||||
bool show_drawings;
|
||||
bool show_eco1;
|
||||
bool show_eco2;
|
||||
bool show_user[45];
|
||||
bool show_footprints_insert;
|
||||
bool show_footprints_normal;
|
||||
bool show_footprints_virtual;
|
||||
@@ -151,21 +152,19 @@ public:
|
||||
bool subtract_mask_from_silk;
|
||||
bool clip_silk_on_via_annuli;
|
||||
bool differentiate_plated_copper;
|
||||
// Board editor copper colors are used only in OpenGL mode if
|
||||
// use_board_editor_copper_colors is true
|
||||
bool use_board_editor_copper_colors;
|
||||
bool use_board_editor_copper_colors; // OpenGL only
|
||||
bool preview_show_board_body;
|
||||
|
||||
/**
|
||||
* return true if platted copper aeras and non platted copper areas must be drawn
|
||||
* using a different color
|
||||
* in OPENGL mode, if use_board_editor_copper_colors, always false
|
||||
* in RAYTRACING mode, use_board_editor_copper_colors is ignored (board editor copper
|
||||
* colors are ignored)
|
||||
*/
|
||||
bool DifferentiatePlatedCopper()
|
||||
{
|
||||
return engine == RENDER_ENGINE::RAYTRACING ? differentiate_plated_copper
|
||||
: differentiate_plated_copper && !use_board_editor_copper_colors;
|
||||
if( engine == RENDER_ENGINE::OPENGL && use_board_editor_copper_colors )
|
||||
return false;
|
||||
|
||||
return differentiate_plated_copper;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <board.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/eda_3d_actions.h>
|
||||
@@ -48,44 +47,87 @@
|
||||
/// Render Row abbreviation to reduce source width.
|
||||
#define RR APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D
|
||||
|
||||
// clang-format off
|
||||
/// Template for object appearance settings
|
||||
const APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D APPEARANCE_CONTROLS_3D::s_layerSettings[] = {
|
||||
|
||||
// text id tooltip
|
||||
RR( _HKI( "Board Body" ), LAYER_3D_BOARD, _HKI( "Show board body" ) ),
|
||||
RR( _HKI( "F.Cu" ), LAYER_3D_COPPER_TOP, _HKI( "Show front copper / surface finish color" ) ),
|
||||
RR( _HKI( "B.Cu" ), LAYER_3D_COPPER_BOTTOM, _HKI( "Show back copper / surface finish color" ) ),
|
||||
RR( _HKI( "Adhesive" ), LAYER_3D_ADHESIVE, _HKI( "Show adhesive" ) ),
|
||||
RR( _HKI( "Solder Paste" ), LAYER_3D_SOLDERPASTE, _HKI( "Show solder paste" ) ),
|
||||
RR( _HKI( "F.Silkscreen" ), LAYER_3D_SILKSCREEN_TOP, _HKI( "Show front silkscreen" ) ),
|
||||
RR( _HKI( "B.Silkscreen" ), LAYER_3D_SILKSCREEN_BOTTOM, _HKI( "Show back silkscreen" ) ),
|
||||
RR( _HKI( "F.Mask" ), LAYER_3D_SOLDERMASK_TOP, _HKI( "Show front solder mask" ) ),
|
||||
RR( _HKI( "B.Mask" ), LAYER_3D_SOLDERMASK_BOTTOM, _HKI( "Show back solder mask" ) ),
|
||||
RR( _HKI( "User.Drawings" ), LAYER_3D_USER_DRAWINGS, _HKI( "Show user drawings layer" ) ),
|
||||
RR( _HKI( "User.Comments" ), LAYER_3D_USER_COMMENTS, _HKI( "Show user comments layer" ) ),
|
||||
RR( _HKI( "User.Eco1" ), LAYER_3D_USER_ECO1, _HKI( "Show user ECO1 layer" ) ),
|
||||
RR( _HKI( "User.Eco2" ), LAYER_3D_USER_ECO2, _HKI( "Show user ECO2 layer" ) ),
|
||||
// text id tooltip
|
||||
RR( _HKI( "Board Body" ), LAYER_3D_BOARD, _HKI( "Show board body" ) ),
|
||||
RR( wxS( "F.Cu" ), LAYER_3D_COPPER_TOP, _HKI( "Show front copper / surface finish color" ) ),
|
||||
RR( wxS( "B.Cu" ), LAYER_3D_COPPER_BOTTOM, _HKI( "Show back copper / surface finish color" ) ),
|
||||
RR( _HKI( "Adhesive" ), LAYER_3D_ADHESIVE, _HKI( "Show adhesive" ) ),
|
||||
RR( _HKI( "Solder Paste" ), LAYER_3D_SOLDERPASTE, _HKI( "Show solder paste" ) ),
|
||||
RR( wxS( "F.Silkscreen" ), LAYER_3D_SILKSCREEN_TOP, _HKI( "Show front silkscreen" ) ),
|
||||
RR( wxS( "B.Silkscreen" ), LAYER_3D_SILKSCREEN_BOTTOM, _HKI( "Show back silkscreen" ) ),
|
||||
RR( wxS( "F.Mask" ), LAYER_3D_SOLDERMASK_TOP, _HKI( "Show front solder mask" ) ),
|
||||
RR( wxS( "B.Mask" ), LAYER_3D_SOLDERMASK_BOTTOM, _HKI( "Show back solder mask" ) ),
|
||||
RR( wxS( "User.Drawings" ), LAYER_3D_USER_DRAWINGS, _HKI( "Show user drawings layer" ) ),
|
||||
RR( wxS( "User.Comments" ), LAYER_3D_USER_COMMENTS, _HKI( "Show user comments layer" ) ),
|
||||
RR( wxS( "User.Eco1" ), LAYER_3D_USER_ECO1, _HKI( "Show user ECO1 layer" ) ),
|
||||
RR( wxS( "User.Eco2" ), LAYER_3D_USER_ECO2, _HKI( "Show user ECO2 layer" ) ),
|
||||
RR( wxS( "User.1" ), LAYER_3D_USER_1, _HKI( "Show user defined layer 1" ) ),
|
||||
RR( wxS( "User.2" ), LAYER_3D_USER_2, _HKI( "Show user defined layer 2" ) ),
|
||||
RR( wxS( "User.3" ), LAYER_3D_USER_3, _HKI( "Show user defined layer 3" ) ),
|
||||
RR( wxS( "User.4" ), LAYER_3D_USER_4, _HKI( "Show user defined layer 4" ) ),
|
||||
RR( wxS( "User.5" ), LAYER_3D_USER_5, _HKI( "Show user defined layer 5" ) ),
|
||||
RR( wxS( "User.6" ), LAYER_3D_USER_6, _HKI( "Show user defined layer 6" ) ),
|
||||
RR( wxS( "User.7" ), LAYER_3D_USER_7, _HKI( "Show user defined layer 7" ) ),
|
||||
RR( wxS( "User.8" ), LAYER_3D_USER_8, _HKI( "Show user defined layer 8" ) ),
|
||||
RR( wxS( "User.9" ), LAYER_3D_USER_9, _HKI( "Show user defined layer 9" ) ),
|
||||
RR( wxS( "User.10" ), LAYER_3D_USER_10, _HKI( "Show user defined layer 10" ) ),
|
||||
RR( wxS( "User.11" ), LAYER_3D_USER_11, _HKI( "Show user defined layer 11" ) ),
|
||||
RR( wxS( "User.12" ), LAYER_3D_USER_12, _HKI( "Show user defined layer 12" ) ),
|
||||
RR( wxS( "User.13" ), LAYER_3D_USER_13, _HKI( "Show user defined layer 13" ) ),
|
||||
RR( wxS( "User.14" ), LAYER_3D_USER_14, _HKI( "Show user defined layer 14" ) ),
|
||||
RR( wxS( "User.15" ), LAYER_3D_USER_15, _HKI( "Show user defined layer 15" ) ),
|
||||
RR( wxS( "User.16" ), LAYER_3D_USER_16, _HKI( "Show user defined layer 16" ) ),
|
||||
RR( wxS( "User.17" ), LAYER_3D_USER_17, _HKI( "Show user defined layer 17" ) ),
|
||||
RR( wxS( "User.18" ), LAYER_3D_USER_18, _HKI( "Show user defined layer 18" ) ),
|
||||
RR( wxS( "User.19" ), LAYER_3D_USER_19, _HKI( "Show user defined layer 19" ) ),
|
||||
RR( wxS( "User.20" ), LAYER_3D_USER_20, _HKI( "Show user defined layer 20" ) ),
|
||||
RR( wxS( "User.21" ), LAYER_3D_USER_21, _HKI( "Show user defined layer 21" ) ),
|
||||
RR( wxS( "User.22" ), LAYER_3D_USER_22, _HKI( "Show user defined layer 22" ) ),
|
||||
RR( wxS( "User.23" ), LAYER_3D_USER_23, _HKI( "Show user defined layer 23" ) ),
|
||||
RR( wxS( "User.24" ), LAYER_3D_USER_24, _HKI( "Show user defined layer 24" ) ),
|
||||
RR( wxS( "User.25" ), LAYER_3D_USER_25, _HKI( "Show user defined layer 25" ) ),
|
||||
RR( wxS( "User.26" ), LAYER_3D_USER_26, _HKI( "Show user defined layer 26" ) ),
|
||||
RR( wxS( "User.27" ), LAYER_3D_USER_27, _HKI( "Show user defined layer 27" ) ),
|
||||
RR( wxS( "User.28" ), LAYER_3D_USER_28, _HKI( "Show user defined layer 28" ) ),
|
||||
RR( wxS( "User.29" ), LAYER_3D_USER_29, _HKI( "Show user defined layer 29" ) ),
|
||||
RR( wxS( "User.30" ), LAYER_3D_USER_30, _HKI( "Show user defined layer 30" ) ),
|
||||
RR( wxS( "User.31" ), LAYER_3D_USER_31, _HKI( "Show user defined layer 31" ) ),
|
||||
RR( wxS( "User.32" ), LAYER_3D_USER_32, _HKI( "Show user defined layer 32" ) ),
|
||||
RR( wxS( "User.33" ), LAYER_3D_USER_33, _HKI( "Show user defined layer 33" ) ),
|
||||
RR( wxS( "User.34" ), LAYER_3D_USER_34, _HKI( "Show user defined layer 34" ) ),
|
||||
RR( wxS( "User.35" ), LAYER_3D_USER_35, _HKI( "Show user defined layer 35" ) ),
|
||||
RR( wxS( "User.36" ), LAYER_3D_USER_36, _HKI( "Show user defined layer 36" ) ),
|
||||
RR( wxS( "User.37" ), LAYER_3D_USER_37, _HKI( "Show user defined layer 37" ) ),
|
||||
RR( wxS( "User.38" ), LAYER_3D_USER_38, _HKI( "Show user defined layer 38" ) ),
|
||||
RR( wxS( "User.39" ), LAYER_3D_USER_39, _HKI( "Show user defined layer 39" ) ),
|
||||
RR( wxS( "User.40" ), LAYER_3D_USER_40, _HKI( "Show user defined layer 40" ) ),
|
||||
RR( wxS( "User.41" ), LAYER_3D_USER_41, _HKI( "Show user defined layer 41" ) ),
|
||||
RR( wxS( "User.42" ), LAYER_3D_USER_42, _HKI( "Show user defined layer 42" ) ),
|
||||
RR( wxS( "User.43" ), LAYER_3D_USER_43, _HKI( "Show user defined layer 43" ) ),
|
||||
RR( wxS( "User.44" ), LAYER_3D_USER_44, _HKI( "Show user defined layer 44" ) ),
|
||||
RR( wxS( "User.45" ), LAYER_3D_USER_45, _HKI( "Show user defined layer 45" ) ),
|
||||
RR(),
|
||||
RR( _HKI( "Through-hole Models" ), LAYER_3D_TH_MODELS, EDA_3D_ACTIONS::showTHT ),
|
||||
RR( _HKI( "SMD Models" ), LAYER_3D_SMD_MODELS, EDA_3D_ACTIONS::showSMD ),
|
||||
RR( _HKI( "Virtual Models" ), LAYER_3D_VIRTUAL_MODELS, EDA_3D_ACTIONS::showVirtual ),
|
||||
RR( _HKI( "Models not in POS File" ), LAYER_3D_MODELS_NOT_IN_POS,
|
||||
EDA_3D_ACTIONS::showNotInPosFile ),
|
||||
RR( _HKI( "Models marked DNP" ), LAYER_3D_MODELS_MARKED_DNP, EDA_3D_ACTIONS::showDNP ),
|
||||
RR( _HKI( "Model Bounding Boxes" ), LAYER_3D_BOUNDING_BOXES, EDA_3D_ACTIONS::showBBoxes ),
|
||||
RR( _HKI( "Through-hole Models" ), LAYER_3D_TH_MODELS, EDA_3D_ACTIONS::showTHT ),
|
||||
RR( _HKI( "SMD Models" ), LAYER_3D_SMD_MODELS, EDA_3D_ACTIONS::showSMD ),
|
||||
RR( _HKI( "Virtual Models" ), LAYER_3D_VIRTUAL_MODELS, EDA_3D_ACTIONS::showVirtual ),
|
||||
RR( _HKI( "Models not in POS File" ), LAYER_3D_MODELS_NOT_IN_POS, EDA_3D_ACTIONS::showNotInPosFile ),
|
||||
RR( _HKI( "Models marked DNP" ), LAYER_3D_MODELS_MARKED_DNP, EDA_3D_ACTIONS::showDNP ),
|
||||
RR( _HKI( "Model Bounding Boxes" ), LAYER_3D_BOUNDING_BOXES, EDA_3D_ACTIONS::showBBoxes ),
|
||||
RR(),
|
||||
RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
|
||||
RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
|
||||
RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
|
||||
RR( _HKI( "Off-board Silkscreen" ), LAYER_3D_OFF_BOARD_SILK,
|
||||
_HKI( "Do not clip silk layers to board outline" ) ),
|
||||
RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
|
||||
RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
|
||||
RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
|
||||
RR( _HKI( "Off-board Silkscreen" ), LAYER_3D_OFF_BOARD_SILK, _HKI( "Do not clip silk layers to board outline" ) ),
|
||||
RR(),
|
||||
RR( _HKI( "3D Axis" ), LAYER_3D_AXES, EDA_3D_ACTIONS::showAxis ),
|
||||
RR( _HKI( "Background Start" ), LAYER_3D_BACKGROUND_TOP,
|
||||
_HKI( "Background gradient start color" ) ),
|
||||
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM,
|
||||
_HKI( "Background gradient end color" ) ),
|
||||
RR( _HKI( "3D Axis" ), LAYER_3D_AXES, EDA_3D_ACTIONS::showAxis ),
|
||||
RR( _HKI( "Background Start" ), LAYER_3D_BACKGROUND_TOP, _HKI( "Background gradient start color" ) ),
|
||||
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// The list of IDs that can have colors coming from the board stackup, and cannot be
|
||||
// modified if use colors from stackup is activated
|
||||
@@ -135,7 +177,6 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
cfg->m_UseStackupColors = aEvent.IsChecked();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
m_frame->NewDisplay( true );
|
||||
} );
|
||||
|
||||
@@ -152,7 +193,6 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
|
||||
cfg->m_Render.use_board_editor_copper_colors = aEvent.IsChecked();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
m_frame->NewDisplay( true );
|
||||
} );
|
||||
|
||||
@@ -272,7 +312,13 @@ void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
|
||||
rebuildControls();
|
||||
|
||||
UpdateLayerCtls();
|
||||
syncLayerPresetSelection();
|
||||
|
||||
const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
|
||||
|
||||
if( currentPreset == FOLLOW_PCB || currentPreset == FOLLOW_PLOT_SETTINGS )
|
||||
updateLayerPresetWidget( currentPreset );
|
||||
else
|
||||
syncLayerPresetSelection();
|
||||
}
|
||||
|
||||
|
||||
@@ -410,6 +456,10 @@ void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisibl
|
||||
|
||||
default:
|
||||
visibleLayers.set( aLayer, isVisible );
|
||||
|
||||
if( aLayer >= LAYER_3D_USER_1 && aLayer <= LAYER_3D_USER_45 )
|
||||
killFollow = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -443,7 +493,6 @@ void APPEARANCE_CONTROLS_3D::onColorSwatchChanged( COLOR_SWATCH* aSwatch )
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
|
||||
m_frame->GetAdapter().SetVisibleLayers( visibleLayers );
|
||||
m_frame->GetAdapter().SetLayerColors( colors );
|
||||
|
||||
int layer = aSwatch->GetId();
|
||||
COLOR4D newColor = aSwatch->GetSwatchColor();
|
||||
@@ -457,7 +506,12 @@ void APPEARANCE_CONTROLS_3D::onColorSwatchChanged( COLOR_SWATCH* aSwatch )
|
||||
|
||||
m_frame->GetAdapter().SetLayerColors( colors );
|
||||
|
||||
syncLayerPresetSelection();
|
||||
const wxString& currentPreset = m_frame->GetAdapter().m_Cfg->m_CurrentPreset;
|
||||
|
||||
if( currentPreset == FOLLOW_PCB || currentPreset == FOLLOW_PLOT_SETTINGS )
|
||||
updateLayerPresetWidget( currentPreset );
|
||||
else
|
||||
syncLayerPresetSelection();
|
||||
|
||||
m_frame->NewDisplay( true );
|
||||
}
|
||||
@@ -470,6 +524,7 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
std::bitset<LAYER_3D_END> visibleLayers = m_frame->GetAdapter().GetVisibleLayers();
|
||||
std::map<int, COLOR4D> colors = m_frame->GetAdapter().GetLayerColors();
|
||||
std::map<int, COLOR4D> defaultColors = m_frame->GetAdapter().GetDefaultColors();
|
||||
LSET enabled = m_frame->GetBoard()->GetEnabledLayers();
|
||||
|
||||
m_layerSettings.clear();
|
||||
m_layersOuterSizer->Clear( true );
|
||||
@@ -524,8 +579,13 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
|
||||
sizer->AddSpacer( 5 );
|
||||
|
||||
wxStaticText* label = new wxStaticText( m_windowLayers, layer,
|
||||
aSetting->GetLabel() );
|
||||
wxString layerName = aSetting->GetLabel();
|
||||
PCB_LAYER_ID boardLayer = Map3DLayerToPCBLayer( layer );
|
||||
|
||||
if( boardLayer != UNDEFINED_LAYER )
|
||||
layerName = m_frame->GetBoard()->GetLayerName( boardLayer );
|
||||
|
||||
wxStaticText* label = new wxStaticText( m_windowLayers, layer, layerName );
|
||||
label->Wrap( -1 );
|
||||
label->SetToolTip( aSetting->GetTooltip() );
|
||||
|
||||
@@ -570,9 +630,18 @@ void APPEARANCE_CONTROLS_3D::rebuildLayers()
|
||||
std::unique_ptr<APPEARANCE_SETTING_3D>& setting = m_layerSettings.back();
|
||||
|
||||
if( setting->m_Spacer )
|
||||
{
|
||||
m_layersOuterSizer->AddSpacer( m_pointSize );
|
||||
}
|
||||
else if( setting->m_Id >= LAYER_3D_USER_1 && setting->m_Id <= LAYER_3D_USER_45 )
|
||||
{
|
||||
if( enabled.test( Map3DLayerToPCBLayer( setting->m_Id ) ) )
|
||||
appendLayer( setting );
|
||||
}
|
||||
else
|
||||
{
|
||||
appendLayer( setting );
|
||||
}
|
||||
|
||||
m_layerSettingsMap[setting->m_Id] = setting.get();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "panel_preview_3d_model.h"
|
||||
#include <dialogs/dialog_unit_entry.h>
|
||||
#include <3d_canvas/eda_3d_canvas.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
#include <tools/eda_3d_actions.h>
|
||||
@@ -64,12 +65,11 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_dummyBoard = new BOARD();
|
||||
|
||||
m_dummyBoard->SetProject( &aFrame->Prj(), true );
|
||||
m_dummyBoard->SetEmbeddedFilesDelegate( aFrame->GetBoard() );
|
||||
|
||||
// This board will only be used to hold a footprint for viewing
|
||||
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
|
||||
|
||||
m_bodyStyleShowAll = true;
|
||||
|
||||
BOARD_DESIGN_SETTINGS parent_bds = aFrame->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS& dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( parent_bds.GetBoardThickness() );
|
||||
@@ -225,16 +225,6 @@ void PANEL_PREVIEW_3D_MODEL::loadSettings()
|
||||
m_previewPane->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
|
||||
m_previewPane->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
|
||||
m_previewPane->SetProjectionMode( cfg->m_Camera.projection_mode );
|
||||
|
||||
// Ensure the board body is always shown, and do not use the settings of the 3D viewer
|
||||
cfg->m_Render.show_copper_top = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_copper_bottom = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_soldermask_top = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_soldermask_bottom = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_solderpaste = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_zones = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_board_body = m_bodyStyleShowAll;
|
||||
cfg->m_Render.use_board_editor_copper_colors = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,13 +395,7 @@ void PANEL_PREVIEW_3D_MODEL::setBodyStyleView( wxCommandEvent& event )
|
||||
if( !cfg )
|
||||
return;
|
||||
|
||||
m_bodyStyleShowAll = !m_bodyStyleShowAll;
|
||||
|
||||
cfg->m_Render.show_soldermask_top = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_soldermask_bottom = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_solderpaste = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_zones = m_bodyStyleShowAll;
|
||||
cfg->m_Render.show_board_body = m_bodyStyleShowAll;
|
||||
cfg->m_Render.preview_show_board_body = !cfg->m_Render.preview_show_board_body;
|
||||
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Refresh();
|
||||
@@ -444,7 +428,9 @@ void PANEL_PREVIEW_3D_MODEL::View3DSettings( wxCommandEvent& event )
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::doIncrementScale( wxSpinEvent& event, double aSign )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( event.GetEventObject() );
|
||||
|
||||
wxCHECK( spinCtrl, /* void */ );
|
||||
|
||||
wxTextCtrl * textCtrl = xscale;
|
||||
|
||||
@@ -471,7 +457,10 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementScale( wxSpinEvent& event, double aSign
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::doIncrementRotation( wxSpinEvent& aEvent, double aSign )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) aEvent.GetEventObject();
|
||||
wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( aEvent.GetEventObject() );
|
||||
|
||||
wxCHECK( spinCtrl, /* void */ );
|
||||
|
||||
wxTextCtrl* textCtrl = xrot;
|
||||
|
||||
if( spinCtrl == m_spinYrot )
|
||||
@@ -497,7 +486,9 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementRotation( wxSpinEvent& aEvent, double aS
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign )
|
||||
{
|
||||
wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
|
||||
wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( event.GetEventObject() );
|
||||
|
||||
wxCHECK( spinCtrl, /* void */ );
|
||||
|
||||
wxTextCtrl * textCtrl = xoff;
|
||||
|
||||
@@ -533,7 +524,9 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onMouseWheelScale( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
|
||||
|
||||
wxCHECK( textCtrl, /* void */ );
|
||||
|
||||
double step = SCALE_INCREMENT;
|
||||
|
||||
@@ -556,7 +549,9 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelScale( wxMouseEvent& event )
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onMouseWheelRot( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
|
||||
|
||||
wxCHECK( textCtrl, /* void */ );
|
||||
|
||||
double step = ROTATION_INCREMENT;
|
||||
|
||||
@@ -579,7 +574,9 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelRot( wxMouseEvent& event )
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onMouseWheelOffset( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
|
||||
|
||||
wxCHECK( textCtrl, /* void */ );
|
||||
|
||||
double step_mm = OFFSET_INCREMENT_MM;
|
||||
|
||||
|
||||
@@ -222,11 +222,11 @@ private:
|
||||
int m_selected; /// Index into m_parentInfoList
|
||||
|
||||
EDA_UNITS m_userUnits;
|
||||
bool m_bodyStyleShowAll; /// true if the board body is show
|
||||
/// The 3d viewer Render initial settings (must be saved and restored)
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS m_initialRender;
|
||||
|
||||
std::unique_ptr<NL_FOOTPRINT_PROPERTIES_PLUGIN> m_spaceMouse;
|
||||
/// The 3d viewer Render initial settings (must be saved and restored)
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS m_initialRender;
|
||||
|
||||
std::unique_ptr<NL_FOOTPRINT_PROPERTIES_PLUGIN> m_spaceMouse;
|
||||
};
|
||||
|
||||
#endif // PANEL_PREVIEW_3D_MODEL_H
|
||||
|
||||
@@ -37,7 +37,7 @@ unset(_Python_NAMES)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
# Disabling the "search every possible place" code for now
|
||||
# see https://gitlab.com/kicad/code/kicad/-/issues/8553
|
||||
|
||||
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonLibs_FIND_VERSION)
|
||||
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.1" )
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.2" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -432,6 +432,7 @@ set( COMMON_WIDGET_SRCS
|
||||
widgets/gal_options_panel_base.cpp
|
||||
widgets/grid_bitmap_toggle.cpp
|
||||
widgets/grid_button.cpp
|
||||
widgets/grid_checkbox.cpp
|
||||
widgets/grid_color_swatch_helpers.cpp
|
||||
widgets/grid_combobox.cpp
|
||||
widgets/grid_icon_text_helpers.cpp
|
||||
@@ -811,7 +812,6 @@ set( PCB_COMMON_SRCS
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/kicad_netlist_reader.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/legacy_netlist_reader.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/netlist_reader.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pad_custom_shape_functions.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_draw_panel_gal.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/pcb_netlist.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_origin_transforms.cpp
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <magic_enum.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/regex.h>
|
||||
#include <wx/stdstream.h>
|
||||
|
||||
@@ -208,7 +208,7 @@ bool BITMAP_BASE::SaveImageData( wxOutputStream& aOutStream ) const
|
||||
else
|
||||
{
|
||||
// Write the contents of m_imageData to the stream.
|
||||
aOutStream.Write( m_imageData.GetData(), m_imageData.GetBufSize() );
|
||||
aOutStream.Write( m_imageData.GetData(), m_imageData.GetDataLen() );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+5
-3
@@ -118,11 +118,12 @@ wxString ExpandTextVars( const wxString& aSource,
|
||||
}
|
||||
|
||||
|
||||
wxString GetTextVars( const wxString& aSource )
|
||||
wxString GetGeneratedFieldDisplayName( const wxString& aSource )
|
||||
{
|
||||
std::function<bool( wxString* )> tokenExtractor =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
*token = *token; // token value is the token name
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -130,9 +131,10 @@ wxString GetTextVars( const wxString& aSource )
|
||||
}
|
||||
|
||||
|
||||
bool IsTextVar( const wxString& aSource )
|
||||
bool IsGeneratedField( const wxString& aSource )
|
||||
{
|
||||
return aSource.StartsWith( wxS( "${" ) );
|
||||
static wxRegEx expr( wxS( "^\\$\\{\\w*\\}$" ) );
|
||||
return expr.Matches( aSource );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
#include <kicommon.h>
|
||||
#include <lib_id.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
|
||||
class KICOMMON_API DESIGN_BLOCK
|
||||
|
||||
@@ -72,7 +72,9 @@ std::vector<SEARCH_TERM> DESIGN_BLOCK_INFO::GetSearchTerms()
|
||||
{
|
||||
std::vector<SEARCH_TERM> terms;
|
||||
|
||||
terms.emplace_back( SEARCH_TERM( GetLibNickname(), 4 ) );
|
||||
terms.emplace_back( SEARCH_TERM( GetName(), 8 ) );
|
||||
terms.emplace_back( SEARCH_TERM( GetLIB_ID().Format(), 16 ) );
|
||||
|
||||
wxStringTokenizer keywordTokenizer( GetKeywords(), wxS( " " ), wxTOKEN_STRTOK );
|
||||
|
||||
|
||||
@@ -622,6 +622,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
|
||||
ADD_DEV( wxT( "Nick Østergaard" ), CONTRIB_DEV );
|
||||
ADD_DEV( wxT( "木 王" ), CONTRIB_DEV );
|
||||
ADD_DEV( wxT( "wh201906" ), CONTRIB_DEV );
|
||||
|
||||
// The document writers
|
||||
#define DOC_TEAM _( "Documentation Team" )
|
||||
|
||||
+39
-50
@@ -42,43 +42,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
/// Toggle a window's "enable" status to disabled, then enabled on destruction.
|
||||
class WDO_ENABLE_DISABLE
|
||||
{
|
||||
wxWindow* m_win;
|
||||
|
||||
public:
|
||||
|
||||
WDO_ENABLE_DISABLE( wxWindow* aWindow ) :
|
||||
m_win( aWindow )
|
||||
{
|
||||
if( m_win )
|
||||
m_win->Disable();
|
||||
}
|
||||
|
||||
~WDO_ENABLE_DISABLE()
|
||||
{
|
||||
if( m_win )
|
||||
{
|
||||
m_win->Enable();
|
||||
m_win->Raise(); // let's focus back on the parent window
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendForTrueModal()
|
||||
{
|
||||
if( m_win )
|
||||
m_win->Enable();
|
||||
}
|
||||
|
||||
void ResumeAfterTrueModal()
|
||||
{
|
||||
if( m_win )
|
||||
m_win->Disable();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( DIALOG_SHIM, wxDialog )
|
||||
EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
|
||||
END_EVENT_TABLE()
|
||||
@@ -521,15 +484,7 @@ int DIALOG_SHIM::ShowModal()
|
||||
|
||||
int DIALOG_SHIM::ShowQuasiModal()
|
||||
{
|
||||
// This is an exception safe way to zero a pointer before returning.
|
||||
// Yes, even though DismissModal() clears this first normally, this is
|
||||
// here in case there's an exception before the dialog is dismissed.
|
||||
struct NULLER
|
||||
{
|
||||
void*& m_what;
|
||||
NULLER( void*& aPtr ) : m_what( aPtr ) {}
|
||||
~NULLER() { m_what = nullptr; } // indeed, set it to NULL on destruction
|
||||
} clear_this( (void*&) m_qmodal_loop );
|
||||
NULLER raii_nuller( (void*&) m_qmodal_loop );
|
||||
|
||||
// release the mouse if it's currently captured as the window having it
|
||||
// will be disabled when this dialog is shown -- but will still keep the
|
||||
@@ -545,7 +500,7 @@ int DIALOG_SHIM::ShowQuasiModal()
|
||||
"window?" ) );
|
||||
|
||||
// quasi-modal: disable only my "optimal" parent
|
||||
m_qmodal_parent_disabler = new WDO_ENABLE_DISABLE( parent );
|
||||
m_qmodal_parent_disabler = new WINDOW_DISABLER( parent );
|
||||
|
||||
// Apple in its infinite wisdom will raise a disabled window before even passing
|
||||
// us the event, so we have no way to stop it. Instead, we must set an order on
|
||||
@@ -698,9 +653,43 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
return;
|
||||
}
|
||||
}
|
||||
// shift-return (Mac default) or Ctrl-Return (GTK) for OK
|
||||
else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
&& ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
|
||||
// shift-return (Mac default) or Ctrl-Return (GTK) for new line input
|
||||
else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ShiftDown() )
|
||||
{
|
||||
wxObject* eventSource = aEvt.GetEventObject();
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( eventSource ) )
|
||||
{
|
||||
#if defined( __WXMAC__ ) || defined( __WXMSW__ )
|
||||
wxString eol = "\r\n";
|
||||
#else
|
||||
wxString eol = "\n";
|
||||
#endif
|
||||
|
||||
long pos = textCtrl->GetInsertionPoint();
|
||||
textCtrl->WriteText( eol );
|
||||
textCtrl->SetInsertionPoint( pos + eol.length() );
|
||||
return;
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( eventSource ) )
|
||||
{
|
||||
wxString eol = "\n";
|
||||
switch( scintilla->GetEOLMode() )
|
||||
{
|
||||
case wxSTC_EOL_CRLF: eol = "\r\n"; break;
|
||||
case wxSTC_EOL_CR: eol = "\r"; break;
|
||||
case wxSTC_EOL_LF: eol = "\n"; break;
|
||||
}
|
||||
|
||||
long pos = scintilla->GetCurrentPos();
|
||||
scintilla->InsertText( pos, eol );
|
||||
scintilla->GotoPos( pos + eol.length() );
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// command-return (Mac default) or Ctrl-Return (GTK) for OK
|
||||
else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER ) && aEvt.ControlDown() )
|
||||
{
|
||||
wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
|
||||
return;
|
||||
|
||||
@@ -27,7 +27,7 @@ DIALOG_LOCKED_ITEMS_QUERY_BASE::DIALOG_LOCKED_ITEMS_QUERY_BASE( wxWindow* parent
|
||||
wxBoxSizer* bSizer4;
|
||||
bSizer4 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_messageLine1 = new wxStaticText( this, wxID_ANY, _("The selection contains %lu locked items."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_messageLine1 = new wxStaticText( this, wxID_ANY, _("The selection contains %zu locked items."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_messageLine1->Wrap( -1 );
|
||||
bSizer4->Add( m_messageLine1, 0, wxALL, 5 );
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">The selection contains %lu locked items.</property>
|
||||
<property name="label">The selection contains %zu locked items.</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
||||
@@ -477,7 +477,7 @@ bool DIALOG_PAGES_SETTINGS::SavePageSettings()
|
||||
if( fileName != BASE_SCREEN::m_DrawingSheetFileName )
|
||||
{
|
||||
wxString fullFileName = m_filenameResolver->ResolvePath( fileName, m_projectPath,
|
||||
m_embeddedFiles );
|
||||
{ m_embeddedFiles } );
|
||||
|
||||
BASE_SCREEN::m_DrawingSheetFileName = fileName;
|
||||
|
||||
|
||||
@@ -50,11 +50,13 @@ int WX_UNIT_ENTRY_DIALOG::GetValue()
|
||||
|
||||
WX_PT_ENTRY_DIALOG::WX_PT_ENTRY_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aCaption,
|
||||
const wxString& aLabelX, const wxString& aLabelY,
|
||||
const VECTOR2I& aDefaultValue ) :
|
||||
const VECTOR2I& aDefaultValue, bool aShowResetButt ) :
|
||||
WX_PT_ENTRY_DIALOG_BASE( ( wxWindow* ) aParent, wxID_ANY, aCaption ),
|
||||
m_unit_binder_x( aParent, m_labelX, m_textCtrlX, m_unitsX, true ),
|
||||
m_unit_binder_y( aParent, m_labelY, m_textCtrlY, m_unitsY, true )
|
||||
{
|
||||
m_ButtonReset->Show( aShowResetButt );
|
||||
|
||||
m_labelX->SetLabel( aLabelX );
|
||||
m_labelY->SetLabel( aLabelY );
|
||||
|
||||
@@ -67,8 +69,7 @@ WX_PT_ENTRY_DIALOG::WX_PT_ENTRY_DIALOG( EDA_DRAW_FRAME* aParent, const wxString&
|
||||
SetInitialFocus( m_textCtrlX );
|
||||
SetupStandardButtons();
|
||||
|
||||
Layout();
|
||||
bSizerMain->Fit( this );
|
||||
finishDialogSettings();
|
||||
}
|
||||
|
||||
|
||||
@@ -76,3 +77,9 @@ VECTOR2I WX_PT_ENTRY_DIALOG::GetValue()
|
||||
{
|
||||
return VECTOR2I( m_unit_binder_x.GetIntValue(), m_unit_binder_y.GetIntValue() );
|
||||
}
|
||||
|
||||
void WX_PT_ENTRY_DIALOG::ResetValues( wxCommandEvent& event )
|
||||
{
|
||||
m_unit_binder_x.SetValue( 0 );
|
||||
m_unit_binder_y.SetValue( 0 );
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -102,8 +102,11 @@ WX_PT_ENTRY_DIALOG_BASE::WX_PT_ENTRY_DIALOG_BASE( wxWindow* parent, wxWindowID i
|
||||
wxBoxSizer* bSizerButtons;
|
||||
bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_ButtonReset = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerButtons->Add( m_ButtonReset, 0, wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
|
||||
|
||||
bSizerButtons->Add( 100, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
bSizerButtons->Add( 30, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_sdbSizer1 = new wxStdDialogButtonSizer();
|
||||
m_sdbSizer1OK = new wxButton( this, wxID_OK );
|
||||
@@ -123,8 +126,14 @@ WX_PT_ENTRY_DIALOG_BASE::WX_PT_ENTRY_DIALOG_BASE( wxWindow* parent, wxWindowID i
|
||||
bSizerMain->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_ButtonReset->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WX_PT_ENTRY_DIALOG_BASE::ResetValues ), NULL, this );
|
||||
}
|
||||
|
||||
WX_PT_ENTRY_DIALOG_BASE::~WX_PT_ENTRY_DIALOG_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_ButtonReset->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WX_PT_ENTRY_DIALOG_BASE::ResetValues ), NULL, this );
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -21,10 +21,12 @@
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class WX_UNIT_ENTRY_DIALOG_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -64,10 +66,15 @@ class WX_PT_ENTRY_DIALOG_BASE : public DIALOG_SHIM
|
||||
wxStaticText* m_labelY;
|
||||
wxTextCtrl* m_textCtrlY;
|
||||
wxStaticText* m_unitsY;
|
||||
wxButton* m_ButtonReset;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
wxButton* m_sdbSizer1Cancel;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void ResetValues( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
WX_PT_ENTRY_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Move Point to Location"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
@@ -86,7 +86,9 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( wxWindow* aParentWindow, EDA_DRA
|
||||
m_netNames( aNetNames ),
|
||||
m_lastCheckedTicker( 0 ),
|
||||
m_hoveredCol( -1 ),
|
||||
m_lastNetclassGridWidth( -1 )
|
||||
m_lastNetclassGridWidth( -1 ),
|
||||
m_sortAsc( false ),
|
||||
m_sortCol( 0 )
|
||||
{
|
||||
// Clear and re-load each time. Language (or darkmode) might have changed.
|
||||
g_lineStyleIcons.clear();
|
||||
@@ -232,6 +234,11 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( wxWindow* aParentWindow, EDA_DRA
|
||||
&PANEL_SETUP_NETCLASSES::OnNetclassGridMouseEvent,
|
||||
this );
|
||||
|
||||
// Allow sorting assignments by column
|
||||
m_assignmentGrid->Connect(
|
||||
wxEVT_GRID_LABEL_LEFT_CLICK,
|
||||
wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassAssignmentSort ), nullptr, this );
|
||||
|
||||
m_frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
|
||||
|
||||
m_netclassGrid->EndBatch();
|
||||
@@ -275,6 +282,10 @@ PANEL_SETUP_NETCLASSES::~PANEL_SETUP_NETCLASSES()
|
||||
wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging ),
|
||||
nullptr, this );
|
||||
|
||||
m_assignmentGrid->Disconnect(
|
||||
wxEVT_GRID_LABEL_LEFT_CLICK,
|
||||
wxGridEventHandler( PANEL_SETUP_NETCLASSES::OnNetclassAssignmentSort ), nullptr, this );
|
||||
|
||||
m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_NETCLASSES::onUnitsChanged, this );
|
||||
}
|
||||
|
||||
@@ -617,6 +628,57 @@ void PANEL_SETUP_NETCLASSES::OnNetclassGridCellChanging( wxGridEvent& event )
|
||||
}
|
||||
}
|
||||
|
||||
void PANEL_SETUP_NETCLASSES::OnNetclassAssignmentSort( wxGridEvent& event )
|
||||
{
|
||||
event.Skip();
|
||||
|
||||
if( !m_assignmentGrid->CommitPendingChanges() )
|
||||
return;
|
||||
|
||||
if( ( event.GetCol() < 0 ) || ( event.GetCol() >= m_assignmentGrid->GetNumberCols() ) )
|
||||
return;
|
||||
|
||||
// Toggle sort order if the same column is clicked
|
||||
if( event.GetCol() != m_sortCol )
|
||||
{
|
||||
m_sortCol = event.GetCol();
|
||||
m_sortAsc = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sortAsc = !m_sortAsc;
|
||||
}
|
||||
|
||||
std::vector<std::pair<wxString, wxString>> netclassesassignments;
|
||||
netclassesassignments.reserve( m_assignmentGrid->GetNumberRows() );
|
||||
|
||||
for( int row = 0; row < m_assignmentGrid->GetNumberRows(); ++row )
|
||||
{
|
||||
netclassesassignments.emplace_back( m_assignmentGrid->GetCellValue( row, 0 ),
|
||||
m_assignmentGrid->GetCellValue( row, 1 ) );
|
||||
}
|
||||
|
||||
std::sort( netclassesassignments.begin(), netclassesassignments.end(),
|
||||
[this]( const std::pair<wxString, wxString>& assign1,
|
||||
const std::pair<wxString, wxString>& assign2 )
|
||||
{
|
||||
const wxString& str1 = ( m_sortCol == 0 ) ? assign1.first : assign1.second;
|
||||
const wxString& str2 = ( m_sortCol == 0 ) ? assign2.first : assign2.second;
|
||||
return m_sortAsc ? ( str1 < str2 ) : ( str1 > str2 );
|
||||
} );
|
||||
|
||||
m_assignmentGrid->ClearRows();
|
||||
m_assignmentGrid->AppendRows( netclassesassignments.size() );
|
||||
|
||||
int row = 0;
|
||||
|
||||
for( const auto& [pattern, netclassName] : netclassesassignments )
|
||||
{
|
||||
m_assignmentGrid->SetCellValue( row, 0, pattern );
|
||||
m_assignmentGrid->SetCellValue( row, 1, netclassName );
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
void PANEL_SETUP_NETCLASSES::OnNetclassGridMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
|
||||
@@ -160,11 +160,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
Connect( m_refreshTimer.GetId(), wxEVT_TIMER,
|
||||
wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onRefreshTimer ), nullptr, this );
|
||||
|
||||
// Set up timer to execute OnShow() method when the window appears on the screen
|
||||
m_onShowTimer.SetOwner( this );
|
||||
Connect( m_onShowTimer.GetId(), wxEVT_TIMER,
|
||||
wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onShowTimer ), nullptr, this );
|
||||
m_onShowTimer.Start( 10 );
|
||||
Connect( wxEVT_SHOW, wxShowEventHandler( EDA_DRAW_PANEL_GAL::onShowEvent ), nullptr, this );
|
||||
}
|
||||
|
||||
|
||||
@@ -443,6 +439,8 @@ void EDA_DRAW_PANEL_GAL::StopDrawing()
|
||||
m_refreshTimer.Stop();
|
||||
m_drawingEnabled = false;
|
||||
|
||||
Disconnect( wxEVT_SHOW, wxShowEventHandler( EDA_DRAW_PANEL_GAL::onShowEvent ), nullptr, this );
|
||||
|
||||
Disconnect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr, this );
|
||||
|
||||
Disconnect( wxEVT_IDLE, wxIdleEventHandler( EDA_DRAW_PANEL_GAL::onIdle ), nullptr, this );
|
||||
@@ -650,11 +648,10 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
|
||||
void EDA_DRAW_PANEL_GAL::onShowEvent( wxShowEvent& aEvent )
|
||||
{
|
||||
if( m_gal && m_gal->IsInitialized() && m_gal->IsVisible() )
|
||||
{
|
||||
m_onShowTimer.Stop();
|
||||
OnShow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,22 +503,6 @@ void EDA_BASE_FRAME::ReCreateMenuBar()
|
||||
}
|
||||
|
||||
|
||||
void EDA_BASE_FRAME::SetMenuBar( wxMenuBar* menu_bar )
|
||||
{
|
||||
wxFrame::SetMenuBar( menu_bar );
|
||||
|
||||
// Move Help menu back to end of menubar
|
||||
|
||||
int pos = GetMenuBar()->FindMenu( _( "&Help" ) + wxS( " " ) );
|
||||
|
||||
if( pos != wxNOT_FOUND )
|
||||
{
|
||||
wxMenu* helpMenu = GetMenuBar()->Remove( pos );
|
||||
GetMenuBar()->Append( helpMenu, _( "&Help" ) + wxS( " " ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
|
||||
{
|
||||
COMMON_CONTROL* commonControl = m_toolManager->GetTool<COMMON_CONTROL>();
|
||||
@@ -534,13 +518,7 @@ void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
|
||||
helpMenu->AppendSeparator();
|
||||
helpMenu->Add( ACTIONS::about );
|
||||
|
||||
// Trailing space keeps OSX from hijacking our menu (and disabling everything in it).
|
||||
aMenuBar->Append( helpMenu, _( "&Help" ) + wxS( " " ) );
|
||||
|
||||
// This change is only needed on macOS, and creates a bug on Windows
|
||||
#ifdef __WXMAC__
|
||||
helpMenu->wxMenu::SetTitle( _( "&Help" ) + wxS( " " ) );
|
||||
#endif
|
||||
aMenuBar->Append( helpMenu, _( "&Help" ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-5
@@ -60,7 +60,7 @@ static const wxFileTypeInfo EDAfallbacks[] =
|
||||
|
||||
|
||||
bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT* aProject,
|
||||
SEARCH_STACK* aPaths, EMBEDDED_FILES* aFiles )
|
||||
SEARCH_STACK* aPaths, std::vector<EMBEDDED_FILES*> aFilesStack )
|
||||
{
|
||||
wxString docname;
|
||||
wxString fullfilename;
|
||||
@@ -87,7 +87,7 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !aFiles )
|
||||
if( aFilesStack.empty() )
|
||||
{
|
||||
wxLogTrace( wxT( "KICAD_EMBED" ),
|
||||
wxT( "No EMBEDDED_FILES object provided for kicad_embed URI" ) );
|
||||
@@ -101,9 +101,13 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
return false;
|
||||
}
|
||||
|
||||
docname = docname.Mid( 14 );
|
||||
docname = docname.Mid( wxString( FILEEXT::KiCadUriPrefix + "://" ).length() );
|
||||
|
||||
wxFileName temp_file = aFiles->GetTemporaryFileName( docname );
|
||||
wxFileName temp_file = aFilesStack[0]->GetTemporaryFileName( docname );
|
||||
int ii = 1;
|
||||
|
||||
while( !temp_file.IsOk() && ii < (int) aFilesStack.size() )
|
||||
temp_file = aFilesStack[ii++]->GetTemporaryFileName( docname );
|
||||
|
||||
if( !temp_file.IsOk() )
|
||||
{
|
||||
@@ -114,7 +118,8 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
|
||||
wxLogTrace( wxT( "KICAD_EMBED" ),
|
||||
wxT( "Opening embedded file '%s' as '%s'" ),
|
||||
docname, temp_file.GetFullPath() );
|
||||
docname,
|
||||
temp_file.GetFullPath() );
|
||||
docname = temp_file.GetFullPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1236,7 +1236,7 @@ void EDA_DRAW_FRAME::ShowChangedLanguage()
|
||||
|
||||
void EDA_DRAW_FRAME::UpdateProperties()
|
||||
{
|
||||
if( !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )
|
||||
if( m_isClosing || !m_propertiesPanel || !m_propertiesPanel->IsShownOnScreen() )
|
||||
return;
|
||||
|
||||
m_propertiesPanel->UpdateData();
|
||||
|
||||
+6
-3
@@ -39,7 +39,8 @@ EDA_ITEM::EDA_ITEM( EDA_ITEM* parent, KICAD_T idType, bool isSCH_ITEM, bool isBO
|
||||
m_structType( idType ),
|
||||
m_flags( 0 ),
|
||||
m_parent( parent ),
|
||||
m_forceVisible( false )
|
||||
m_forceVisible( false ),
|
||||
m_isRollover( false )
|
||||
{ }
|
||||
|
||||
|
||||
@@ -48,7 +49,8 @@ EDA_ITEM::EDA_ITEM( KICAD_T idType, bool isSCH_ITEM, bool isBOARD_ITEM ) :
|
||||
m_structType( idType ),
|
||||
m_flags( 0 ),
|
||||
m_parent( nullptr ),
|
||||
m_forceVisible( false )
|
||||
m_forceVisible( false ),
|
||||
m_isRollover( false )
|
||||
{ }
|
||||
|
||||
|
||||
@@ -58,7 +60,8 @@ EDA_ITEM::EDA_ITEM( const EDA_ITEM& base ) :
|
||||
m_structType( base.m_structType ),
|
||||
m_flags( base.m_flags ),
|
||||
m_parent( base.m_parent ),
|
||||
m_forceVisible( base.m_forceVisible )
|
||||
m_forceVisible( base.m_forceVisible ),
|
||||
m_isRollover( false )
|
||||
{
|
||||
SetForcedTransparency( base.GetForcedTransparency() );
|
||||
}
|
||||
|
||||
+141
-22
@@ -1416,6 +1416,122 @@ std::vector<VECTOR2I> EDA_SHAPE::GetRectCorners() const
|
||||
}
|
||||
|
||||
|
||||
std::vector<VECTOR2I> EDA_SHAPE::GetCornersInSequence( EDA_ANGLE angle ) const
|
||||
{
|
||||
std::vector<VECTOR2I> pts;
|
||||
|
||||
angle.Normalize();
|
||||
|
||||
BOX2I bbox = getBoundingBox();
|
||||
bbox.Normalize();
|
||||
|
||||
if( angle.IsCardinal() )
|
||||
{
|
||||
if( angle == ANGLE_0 )
|
||||
{
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
|
||||
}
|
||||
else if( angle == ANGLE_90 )
|
||||
{
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
|
||||
}
|
||||
else if( angle == ANGLE_180 )
|
||||
{
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
|
||||
}
|
||||
else if( angle == ANGLE_270 )
|
||||
{
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
|
||||
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This function was originally located in pcb_textbox.cpp and was later moved to eda_shape.cpp.
|
||||
// As a result of this move, access to getCorners was lost, since it is defined in the PCB_SHAPE
|
||||
// class within pcb_shape.cpp and is not available in the current context.
|
||||
//
|
||||
// Additionally, GetRectCorners() cannot be used here, as it assumes the rectangle is rotated by
|
||||
// a cardinal angle. In non-cardinal cases, it returns incorrect values (e.g., (0, 0)).
|
||||
//
|
||||
// To address this, a portion of the getCorners implementation for SHAPE_T::POLY elements
|
||||
// has been replicated here to restore the correct behavior.
|
||||
std::vector<VECTOR2I> corners;
|
||||
|
||||
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
|
||||
{
|
||||
for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
|
||||
corners.emplace_back( pt );
|
||||
}
|
||||
|
||||
while( corners.size() < 4 )
|
||||
corners.emplace_back( corners.back() + VECTOR2I( 10, 10 ) );
|
||||
|
||||
VECTOR2I minX = corners[0];
|
||||
VECTOR2I maxX = corners[0];
|
||||
VECTOR2I minY = corners[0];
|
||||
VECTOR2I maxY = corners[0];
|
||||
|
||||
for( const VECTOR2I& corner : corners )
|
||||
{
|
||||
if( corner.x < minX.x )
|
||||
minX = corner;
|
||||
|
||||
if( corner.x > maxX.x )
|
||||
maxX = corner;
|
||||
|
||||
if( corner.y < minY.y )
|
||||
minY = corner;
|
||||
|
||||
if( corner.y > maxY.y )
|
||||
maxY = corner;
|
||||
}
|
||||
|
||||
if( angle < ANGLE_90 )
|
||||
{
|
||||
pts.emplace_back( minX );
|
||||
pts.emplace_back( minY );
|
||||
pts.emplace_back( maxX );
|
||||
pts.emplace_back( maxY );
|
||||
}
|
||||
else if( angle < ANGLE_180 )
|
||||
{
|
||||
pts.emplace_back( maxY );
|
||||
pts.emplace_back( minX );
|
||||
pts.emplace_back( minY );
|
||||
pts.emplace_back( maxX );
|
||||
}
|
||||
else if( angle < ANGLE_270 )
|
||||
{
|
||||
pts.emplace_back( maxX );
|
||||
pts.emplace_back( maxY );
|
||||
pts.emplace_back( minX );
|
||||
pts.emplace_back( minY );
|
||||
}
|
||||
else
|
||||
{
|
||||
pts.emplace_back( minY );
|
||||
pts.emplace_back( maxX );
|
||||
pts.emplace_back( maxY );
|
||||
pts.emplace_back( minX );
|
||||
}
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
void EDA_SHAPE::computeArcBBox( BOX2I& aBBox ) const
|
||||
{
|
||||
// Start, end, and each inflection point the arc crosses will enclose the entire arc.
|
||||
@@ -1906,7 +2022,7 @@ int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const
|
||||
|
||||
if( m_shape == SHAPE_T::ARC )
|
||||
{
|
||||
TEST_PT( m_arcCenter, aOther->m_arcCenter );
|
||||
TEST_PT( GetArcMid(), aOther->GetArcMid() );
|
||||
}
|
||||
else if( m_shape == SHAPE_T::BEZIER )
|
||||
{
|
||||
@@ -2220,32 +2336,35 @@ static struct EDA_SHAPE_DESC
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( EDA_SHAPE );
|
||||
|
||||
auto isNotPolygonOrCircle = []( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() != SHAPE_T::POLY && shape->GetShape() != SHAPE_T::CIRCLE;
|
||||
auto isNotPolygonOrCircle =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() != SHAPE_T::POLY && shape->GetShape() != SHAPE_T::CIRCLE;
|
||||
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isCircle = []( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() == SHAPE_T::CIRCLE;
|
||||
auto isCircle =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() == SHAPE_T::CIRCLE;
|
||||
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isRectangle = []( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() == SHAPE_T::RECTANGLE;
|
||||
auto isRectangle =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
// Polygons, unlike other shapes, have no meaningful start or end coordinates
|
||||
if( EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return shape->GetShape() == SHAPE_T::RECTANGLE;
|
||||
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
const wxString shapeProps = _HKI( "Shape Properties" );
|
||||
|
||||
|
||||
@@ -1371,6 +1371,21 @@ static struct EDA_TEXT_DESC
|
||||
propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Mirrored" ),
|
||||
&EDA_TEXT::SetMirrored, &EDA_TEXT::IsMirrored ),
|
||||
textProps );
|
||||
|
||||
auto isField =
|
||||
[]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
if( EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( aItem ) )
|
||||
return item->Type() == SCH_FIELD_T || item->Type() == PCB_FIELD_T;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Visible" ),
|
||||
&EDA_TEXT::SetVisible, &EDA_TEXT::IsVisible ),
|
||||
textProps )
|
||||
.SetAvailableFunc( isField );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Width" ),
|
||||
&EDA_TEXT::SetTextWidth, &EDA_TEXT::GetTextWidth,
|
||||
PROPERTY_DISPLAY::PT_SIZE ),
|
||||
|
||||
@@ -244,7 +244,7 @@ bool FILENAME_RESOLVER::UpdatePathList( const std::vector< SEARCH_PATH >& aPathL
|
||||
|
||||
|
||||
wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxString& aWorkingPath,
|
||||
const EMBEDDED_FILES* aFiles )
|
||||
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( mutex_resolver );
|
||||
|
||||
@@ -266,15 +266,20 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxStri
|
||||
// Check to see if the file is a URI for an embedded file.
|
||||
if( tname.StartsWith( FILEEXT::KiCadUriPrefix + "://" ) )
|
||||
{
|
||||
if( !aFiles )
|
||||
if( aEmbeddedFilesStack.empty() )
|
||||
{
|
||||
wxLogTrace( wxT( "KICAD_EMBED" ),
|
||||
wxT( "No EMBEDDED_FILES object provided for kicad_embed URI" ) );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxString path = tname.Mid( 14 );
|
||||
wxFileName temp_file = aFiles->GetTemporaryFileName( path );
|
||||
wxString path = tname.Mid( wxString( FILEEXT::KiCadUriPrefix + "://" ).length() );
|
||||
|
||||
wxFileName temp_file = aEmbeddedFilesStack[0]->GetTemporaryFileName( path );
|
||||
int ii = 1;
|
||||
|
||||
while( !temp_file.IsOk() && ii < (int) aEmbeddedFilesStack.size() )
|
||||
temp_file = aEmbeddedFilesStack[ii++]->GetTemporaryFileName( path );
|
||||
|
||||
if( !temp_file.IsOk() )
|
||||
{
|
||||
|
||||
@@ -74,7 +74,9 @@ std::vector<SEARCH_TERM> FOOTPRINT_INFO::GetSearchTerms()
|
||||
{
|
||||
std::vector<SEARCH_TERM> terms;
|
||||
|
||||
terms.emplace_back( SEARCH_TERM( GetLibNickname(), 4 ) );
|
||||
terms.emplace_back( SEARCH_TERM( GetName(), 8 ) );
|
||||
terms.emplace_back( SEARCH_TERM( GetLIB_ID().Format(), 16 ) );
|
||||
|
||||
wxStringTokenizer keywordTokenizer( GetKeywords(), wxS( " " ), wxTOKEN_STRTOK );
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <gal/color4d.h>
|
||||
#include <i18n_utility.h>
|
||||
#include <wx/crt.h>
|
||||
|
||||
@@ -232,13 +232,15 @@ void GRID_TRICKS::onGridCellLeftClick( wxGridEvent& aEvent )
|
||||
|
||||
wxString newVal = m_grid->GetCellValue( row, col );
|
||||
|
||||
for( int affectedRow = m_sel_row_start; affectedRow < m_sel_row_count; ++affectedRow )
|
||||
for( int otherRow = m_sel_row_start; otherRow < m_sel_row_start + m_sel_row_count; ++otherRow )
|
||||
{
|
||||
if( affectedRow == row )
|
||||
if( otherRow == row )
|
||||
continue;
|
||||
|
||||
m_grid->SetCellValue( affectedRow, col, newVal );
|
||||
m_grid->SetCellValue( otherRow, col, newVal );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,6 +854,9 @@ void GRID_TRICKS::cutcopy( bool doCopy, bool doDelete )
|
||||
// fill txt with a format that is compatible with most spreadsheets
|
||||
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
|
||||
{
|
||||
if( !txt.IsEmpty() )
|
||||
txt += ROW_SEP;
|
||||
|
||||
for( int col = m_sel_col_start; col < m_sel_col_start + m_sel_col_count; ++col )
|
||||
{
|
||||
if( !m_grid->IsColShown( col ) )
|
||||
@@ -870,8 +875,6 @@ void GRID_TRICKS::cutcopy( bool doCopy, bool doDelete )
|
||||
tbl->SetValue( row, col, wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
txt += ROW_SEP;
|
||||
}
|
||||
|
||||
if( doCopy )
|
||||
|
||||
@@ -264,6 +264,16 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
|
||||
point -= shape->GetPosition();
|
||||
}
|
||||
|
||||
//Basic sort of start/end points to try to always draw the same direction (left to right, down to up)
|
||||
//The hashes are summed, so it doesn't matter what order the lines are drawn, only that the same points are used
|
||||
if( points.size() > 1 )
|
||||
{
|
||||
if( points[0].x > points[1].x || points[0].y > points[1].y )
|
||||
{
|
||||
std::swap( points[0], points[1] );
|
||||
}
|
||||
}
|
||||
|
||||
for( VECTOR2I& point : points )
|
||||
hash_combine( ret, point.x, point.y );
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <ctime>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <wx/base64.h>
|
||||
|
||||
#include <kicad_curl/kicad_curl_easy.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <settings/parameters.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/arrstr.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
namespace EASYEDA
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <math/vector2d.h>
|
||||
|
||||
|
||||
|
||||
@@ -88,6 +88,10 @@ JOB_EXPORT_PCB_3D::JOB_EXPORT_PCB_3D() :
|
||||
m_3dparams.m_UseGridOrigin ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "use_drill_origin", &m_3dparams.m_UseDrillOrigin,
|
||||
m_3dparams.m_UseDrillOrigin ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "use_defined_origin", &m_3dparams.m_UseDefinedOrigin,
|
||||
m_3dparams.m_UseDefinedOrigin ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "use_pcb_center_origin", &m_3dparams.m_UsePcbCenterOrigin,
|
||||
m_3dparams.m_UsePcbCenterOrigin ) );
|
||||
m_params.emplace_back(
|
||||
new JOB_PARAM<bool>( "board_only", &m_3dparams.m_BoardOnly, m_3dparams.m_BoardOnly ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "include_unspecified",
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
m_Overwrite( false ),
|
||||
m_UseGridOrigin( false ),
|
||||
m_UseDrillOrigin( false ),
|
||||
m_UseDefinedOrigin( false ),
|
||||
m_UsePcbCenterOrigin( false ),
|
||||
m_IncludeUnspecified( true ),
|
||||
m_IncludeDNP( true ),
|
||||
m_SubstModels( true ),
|
||||
@@ -77,6 +79,8 @@ public:
|
||||
bool m_Overwrite;
|
||||
bool m_UseGridOrigin;
|
||||
bool m_UseDrillOrigin;
|
||||
bool m_UseDefinedOrigin;
|
||||
bool m_UsePcbCenterOrigin;
|
||||
bool m_IncludeUnspecified;
|
||||
bool m_IncludeDNP;
|
||||
bool m_SubstModels;
|
||||
|
||||
@@ -22,13 +22,6 @@
|
||||
#include <jobs/job_registry.h>
|
||||
#include <i18n_utility.h>
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_PDF::DRILL_MARKS,
|
||||
{
|
||||
{ JOB_EXPORT_PCB_PDF::DRILL_MARKS::NO_DRILL_SHAPE, "none" },
|
||||
{ JOB_EXPORT_PCB_PDF::DRILL_MARKS::SMALL_DRILL_SHAPE, "small" },
|
||||
{ JOB_EXPORT_PCB_PDF::DRILL_MARKS::FULL_DRILL_SHAPE, "full" }
|
||||
} )
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_PDF::GEN_MODE,
|
||||
{
|
||||
{ JOB_EXPORT_PCB_PDF::GEN_MODE::ALL_LAYERS_ONE_FILE, "all-layers-one-file" },
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
|
||||
#include <jobs/job_export_pcb_plot.h>
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM( DRILL_MARKS,
|
||||
{
|
||||
{ DRILL_MARKS::NO_DRILL_SHAPE, "none" },
|
||||
{ DRILL_MARKS::SMALL_DRILL_SHAPE, "small" },
|
||||
{ DRILL_MARKS::FULL_DRILL_SHAPE, "full" }
|
||||
} )
|
||||
|
||||
JOB_EXPORT_PCB_PLOT::JOB_EXPORT_PCB_PLOT( PLOT_FORMAT aFormat, const std::string& aType,
|
||||
bool aOutputIsDirectory ) :
|
||||
JOB( aType, aOutputIsDirectory ),
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <kicommon.h>
|
||||
#include <kicommon.h>
|
||||
#include <plotprint_opts.h>
|
||||
#include <layer_ids.h>
|
||||
#include <lseq.h>
|
||||
#include <wx/string.h>
|
||||
@@ -42,6 +42,10 @@ public:
|
||||
|
||||
JOB_EXPORT_PCB_PLOT( PLOT_FORMAT aFormat, const std::string& aType, bool aOutputIsDirectory );
|
||||
|
||||
public:
|
||||
std::optional<wxString> m_argLayers;
|
||||
std::optional<wxString> m_argCommonLayers;
|
||||
|
||||
PLOT_FORMAT m_plotFormat;
|
||||
|
||||
wxString m_filename;
|
||||
@@ -70,13 +74,6 @@ public:
|
||||
///< Layers to include on all individual layer prints
|
||||
LSEQ m_plotOnAllLayersSequence;
|
||||
|
||||
enum class DRILL_MARKS
|
||||
{
|
||||
NO_DRILL_SHAPE = 0,
|
||||
SMALL_DRILL_SHAPE = 1,
|
||||
FULL_DRILL_SHAPE = 2
|
||||
};
|
||||
|
||||
///< Used by SVG & PDF
|
||||
DRILL_MARKS m_drillShapeOption;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class KICOMMON_API JOB_FP_EXPORT_SVG : public JOB
|
||||
public:
|
||||
JOB_FP_EXPORT_SVG();
|
||||
|
||||
public:
|
||||
wxString m_libraryPath;
|
||||
wxString m_footprint;
|
||||
|
||||
@@ -39,13 +40,14 @@ public:
|
||||
|
||||
wxString m_colorTheme;
|
||||
|
||||
bool m_blackAndWhite;
|
||||
bool m_sketchPadsOnFabLayers;
|
||||
bool m_hideDNPFPsOnFabLayers;
|
||||
bool m_sketchDNPFPsOnFabLayers;
|
||||
bool m_crossoutDNPFPsOnFabLayers;
|
||||
bool m_blackAndWhite;
|
||||
bool m_sketchPadsOnFabLayers;
|
||||
bool m_hideDNPFPsOnFabLayers;
|
||||
bool m_sketchDNPFPsOnFabLayers;
|
||||
bool m_crossoutDNPFPsOnFabLayers;
|
||||
|
||||
LSEQ m_printMaskLayer;
|
||||
std::optional<wxString> m_argLayers;
|
||||
LSEQ m_plotLayerSequence;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -35,9 +35,7 @@ JOBS_OUTPUT_ARCHIVE::JOBS_OUTPUT_ARCHIVE() :
|
||||
bool JOBS_OUTPUT_ARCHIVE::OutputPrecheck()
|
||||
{
|
||||
if( m_outputPath.IsEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -51,6 +49,9 @@ bool JOBS_OUTPUT_ARCHIVE::HandleOutputs( const wxString& baseTempPath, PROJECT*
|
||||
wxString outputPath = ExpandTextVars( m_outputPath, aProject );
|
||||
outputPath = ExpandEnvVarSubstitutions( outputPath, aProject );
|
||||
|
||||
if( outputPath.StartsWith( "~" ) )
|
||||
outputPath.Replace( "~", wxGetHomeDir(), false );
|
||||
|
||||
wxFFileOutputStream ostream( outputPath );
|
||||
|
||||
if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
|
||||
@@ -64,14 +65,10 @@ bool JOBS_OUTPUT_ARCHIVE::HandleOutputs( const wxString& baseTempPath, PROJECT*
|
||||
wxString errors;
|
||||
|
||||
if( !AddDirectoryToZip( zipstream, baseTempPath, errors ) )
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
if( !zipstream.Close() )
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -36,33 +36,28 @@ bool JOBS_OUTPUT_FOLDER::HandleOutputs( const wxString& baseTempPath, PROJECT* a
|
||||
wxString outputPath = ExpandTextVars( m_outputPath, aProject );
|
||||
outputPath = ExpandEnvVarSubstitutions( outputPath, aProject );
|
||||
|
||||
if( outputPath.StartsWith( "~" ) )
|
||||
outputPath.Replace( "~", wxGetHomeDir(), false );
|
||||
|
||||
if( !wxFileName::DirExists( outputPath ) )
|
||||
{
|
||||
if( !wxFileName::Mkdir( outputPath, wxS_DIR_DEFAULT ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
wxString errors;
|
||||
|
||||
if( !CopyDirectory( baseTempPath, outputPath, errors ) )
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
return false;
|
||||
|
||||
return success;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool JOBS_OUTPUT_FOLDER::OutputPrecheck()
|
||||
{
|
||||
if( m_outputPath.IsEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <i18n_utility.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <settings/parameters.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <json_conversions.h>
|
||||
|
||||
// Specializations to allow directly reading/writing wxStrings from JSON
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@
|
||||
#include <boost/uuid/entropy_error.hpp>
|
||||
#endif
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <mutex>
|
||||
|
||||
+11
-32
@@ -32,6 +32,7 @@
|
||||
#include <wx/utils.h>
|
||||
#include <wx/evtloop.h>
|
||||
#include <wx/socket.h>
|
||||
#include <core/raii.h>
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME )
|
||||
@@ -103,16 +104,7 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
|
||||
vtable and therefore cross-module capable.
|
||||
*/
|
||||
|
||||
// This is an exception safe way to zero a pointer before returning.
|
||||
// Yes, even though DismissModal() clears this first normally, this is
|
||||
// here in case there's an exception before the dialog is dismissed.
|
||||
struct NULLER
|
||||
{
|
||||
void*& m_what;
|
||||
NULLER( void*& aPtr ) : m_what( aPtr ) {}
|
||||
~NULLER() { m_what = nullptr; } // indeed, set it to NULL on destruction
|
||||
} clear_this( (void*&) m_modal_loop );
|
||||
|
||||
NULLER raii_nuller( (void*&) m_modal_loop );
|
||||
|
||||
m_modal_resultant_parent = aResultantFocusWindow;
|
||||
|
||||
@@ -122,34 +114,21 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
|
||||
SetFocus();
|
||||
|
||||
{
|
||||
// We have to disable all frames but the modal one.
|
||||
// wxWindowDisabler does that, but it also disables all top level windows
|
||||
// We do not want to disable top level windows which are child of the modal one,
|
||||
// if they are enabled.
|
||||
// An example is an aui toolbar which was moved
|
||||
// or a dialog or another frame or miniframe opened by the modal one.
|
||||
wxWindowList wlist = GetChildren();
|
||||
std::vector<wxWindow*> enabledTopLevelWindows;
|
||||
// Using wxWindowDisabler() has two issues: it will disable top-level windows that are
|
||||
// our *children* (such as sub-frames), and it will disable all context menus we try to
|
||||
// put up. Fortunatly we already had to cross this Rubicon for QuasiModal dialogs, so
|
||||
// we re-use that strategy.
|
||||
wxWindow* parent = GetParent();
|
||||
|
||||
for( unsigned ii = 0; ii < wlist.size(); ii++ )
|
||||
{
|
||||
if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
|
||||
enabledTopLevelWindows.push_back( wlist[ii] );
|
||||
}
|
||||
while( parent && !parent->IsTopLevel() )
|
||||
parent = parent->GetParent();
|
||||
|
||||
// exception safe way to disable all top level windows except the modal one,
|
||||
// re-enables only those that were disabled on exit
|
||||
wxWindowDisabler toggle( this );
|
||||
|
||||
for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
|
||||
enabledTopLevelWindows[ii]->Enable( true );
|
||||
WINDOW_DISABLER raii_parent_disabler( parent );
|
||||
|
||||
wxGUIEventLoop event_loop;
|
||||
m_modal_loop = &event_loop;
|
||||
event_loop.Run();
|
||||
|
||||
} // End of scope for some variables.
|
||||
// End nesting before setting focus below.
|
||||
}
|
||||
|
||||
if( aResult )
|
||||
*aResult = m_modal_string;
|
||||
|
||||
@@ -260,3 +260,135 @@ PCB_LAYER_ID BoardLayerFromLegacyId( int aLegacyId )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PCB_LAYER_ID Map3DLayerToPCBLayer( int aLayer )
|
||||
{
|
||||
// NOTE: User_1..User45 are NOT consecutive numbers!
|
||||
|
||||
switch( aLayer )
|
||||
{
|
||||
case LAYER_3D_COPPER_TOP: return F_Cu;
|
||||
case LAYER_3D_COPPER_BOTTOM: return B_Cu;
|
||||
case LAYER_3D_SILKSCREEN_BOTTOM: return B_SilkS;
|
||||
case LAYER_3D_SILKSCREEN_TOP: return F_SilkS;
|
||||
case LAYER_3D_SOLDERMASK_BOTTOM: return B_Mask;
|
||||
case LAYER_3D_SOLDERMASK_TOP: return F_Mask;
|
||||
case LAYER_3D_USER_COMMENTS: return Cmts_User;
|
||||
case LAYER_3D_USER_DRAWINGS: return Dwgs_User;
|
||||
case LAYER_3D_USER_ECO1: return Eco1_User;
|
||||
case LAYER_3D_USER_ECO2: return Eco2_User;
|
||||
case LAYER_3D_USER_1: return User_1;
|
||||
case LAYER_3D_USER_2: return User_2;
|
||||
case LAYER_3D_USER_3: return User_3;
|
||||
case LAYER_3D_USER_4: return User_4;
|
||||
case LAYER_3D_USER_5: return User_5;
|
||||
case LAYER_3D_USER_6: return User_6;
|
||||
case LAYER_3D_USER_7: return User_7;
|
||||
case LAYER_3D_USER_8: return User_8;
|
||||
case LAYER_3D_USER_9: return User_9;
|
||||
case LAYER_3D_USER_10: return User_10;
|
||||
case LAYER_3D_USER_11: return User_11;
|
||||
case LAYER_3D_USER_12: return User_12;
|
||||
case LAYER_3D_USER_13: return User_13;
|
||||
case LAYER_3D_USER_14: return User_14;
|
||||
case LAYER_3D_USER_15: return User_15;
|
||||
case LAYER_3D_USER_16: return User_16;
|
||||
case LAYER_3D_USER_17: return User_17;
|
||||
case LAYER_3D_USER_18: return User_18;
|
||||
case LAYER_3D_USER_19: return User_19;
|
||||
case LAYER_3D_USER_20: return User_20;
|
||||
case LAYER_3D_USER_21: return User_21;
|
||||
case LAYER_3D_USER_22: return User_22;
|
||||
case LAYER_3D_USER_23: return User_23;
|
||||
case LAYER_3D_USER_24: return User_24;
|
||||
case LAYER_3D_USER_25: return User_25;
|
||||
case LAYER_3D_USER_26: return User_26;
|
||||
case LAYER_3D_USER_27: return User_27;
|
||||
case LAYER_3D_USER_28: return User_28;
|
||||
case LAYER_3D_USER_29: return User_29;
|
||||
case LAYER_3D_USER_30: return User_30;
|
||||
case LAYER_3D_USER_31: return User_31;
|
||||
case LAYER_3D_USER_32: return User_32;
|
||||
case LAYER_3D_USER_33: return User_33;
|
||||
case LAYER_3D_USER_34: return User_34;
|
||||
case LAYER_3D_USER_35: return User_35;
|
||||
case LAYER_3D_USER_36: return User_36;
|
||||
case LAYER_3D_USER_37: return User_37;
|
||||
case LAYER_3D_USER_38: return User_38;
|
||||
case LAYER_3D_USER_39: return User_39;
|
||||
case LAYER_3D_USER_40: return User_40;
|
||||
case LAYER_3D_USER_41: return User_41;
|
||||
case LAYER_3D_USER_42: return User_42;
|
||||
case LAYER_3D_USER_43: return User_43;
|
||||
case LAYER_3D_USER_44: return User_44;
|
||||
case LAYER_3D_USER_45: return User_45;
|
||||
default: return UNDEFINED_LAYER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MapPCBLayerTo3DLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
// NOTE: User_1..User45 are NOT consecutive numbers!
|
||||
|
||||
switch( aLayer )
|
||||
{
|
||||
case F_Cu: return LAYER_3D_COPPER_TOP;
|
||||
case B_Cu: return LAYER_3D_COPPER_BOTTOM;
|
||||
case B_SilkS: return LAYER_3D_SILKSCREEN_BOTTOM;
|
||||
case F_SilkS: return LAYER_3D_SILKSCREEN_TOP;
|
||||
case B_Mask: return LAYER_3D_SOLDERMASK_BOTTOM;
|
||||
case F_Mask: return LAYER_3D_SOLDERMASK_TOP;
|
||||
case Cmts_User: return LAYER_3D_USER_COMMENTS;
|
||||
case Dwgs_User: return LAYER_3D_USER_DRAWINGS;
|
||||
case Eco1_User: return LAYER_3D_USER_ECO1;
|
||||
case Eco2_User: return LAYER_3D_USER_ECO2;
|
||||
case User_1: return LAYER_3D_USER_1;
|
||||
case User_2: return LAYER_3D_USER_2;
|
||||
case User_3: return LAYER_3D_USER_3;
|
||||
case User_4: return LAYER_3D_USER_4;
|
||||
case User_5: return LAYER_3D_USER_5;
|
||||
case User_6: return LAYER_3D_USER_6;
|
||||
case User_7: return LAYER_3D_USER_7;
|
||||
case User_8: return LAYER_3D_USER_8;
|
||||
case User_9: return LAYER_3D_USER_9;
|
||||
case User_10: return LAYER_3D_USER_10;
|
||||
case User_11: return LAYER_3D_USER_11;
|
||||
case User_12: return LAYER_3D_USER_12;
|
||||
case User_13: return LAYER_3D_USER_13;
|
||||
case User_14: return LAYER_3D_USER_14;
|
||||
case User_15: return LAYER_3D_USER_15;
|
||||
case User_16: return LAYER_3D_USER_16;
|
||||
case User_17: return LAYER_3D_USER_17;
|
||||
case User_18: return LAYER_3D_USER_18;
|
||||
case User_19: return LAYER_3D_USER_19;
|
||||
case User_20: return LAYER_3D_USER_20;
|
||||
case User_21: return LAYER_3D_USER_21;
|
||||
case User_22: return LAYER_3D_USER_22;
|
||||
case User_23: return LAYER_3D_USER_23;
|
||||
case User_24: return LAYER_3D_USER_24;
|
||||
case User_25: return LAYER_3D_USER_25;
|
||||
case User_26: return LAYER_3D_USER_26;
|
||||
case User_27: return LAYER_3D_USER_27;
|
||||
case User_28: return LAYER_3D_USER_28;
|
||||
case User_29: return LAYER_3D_USER_29;
|
||||
case User_30: return LAYER_3D_USER_30;
|
||||
case User_31: return LAYER_3D_USER_31;
|
||||
case User_32: return LAYER_3D_USER_32;
|
||||
case User_33: return LAYER_3D_USER_33;
|
||||
case User_34: return LAYER_3D_USER_34;
|
||||
case User_35: return LAYER_3D_USER_35;
|
||||
case User_36: return LAYER_3D_USER_36;
|
||||
case User_37: return LAYER_3D_USER_37;
|
||||
case User_38: return LAYER_3D_USER_38;
|
||||
case User_39: return LAYER_3D_USER_39;
|
||||
case User_40: return LAYER_3D_USER_40;
|
||||
case User_41: return LAYER_3D_USER_41;
|
||||
case User_42: return LAYER_3D_USER_42;
|
||||
case User_43: return LAYER_3D_USER_43;
|
||||
case User_44: return LAYER_3D_USER_44;
|
||||
case User_45: return LAYER_3D_USER_45;
|
||||
default: return UNDEFINED_LAYER;
|
||||
}
|
||||
}
|
||||
|
||||
+23
-57
@@ -171,11 +171,11 @@ LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* a
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_NODE_UNIT::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
void LIB_TREE_NODE_UNIT::UpdateScore( const std::vector<std::unique_ptr<EDA_COMBINED_MATCHER>>& aMatchers,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
// aMatcher test results are inherited from parent
|
||||
if( aMatcher )
|
||||
// aMatchers test results are inherited from parent
|
||||
if( !aMatchers.empty() )
|
||||
m_Score = m_Parent->m_Score;
|
||||
|
||||
// aFilter test is subtractive
|
||||
@@ -183,7 +183,7 @@ void LIB_TREE_NODE_UNIT::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxSt
|
||||
m_Score = 0;
|
||||
|
||||
// show all nodes if no search/filter/etc. criteria are given
|
||||
if( !aMatcher && aLib.IsEmpty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
if( aMatchers.empty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
m_Score = 1;
|
||||
}
|
||||
|
||||
@@ -243,35 +243,24 @@ void LIB_TREE_NODE_ITEM::Update( LIB_TREE_ITEM* aItem )
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_NODE_ITEM::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
void LIB_TREE_NODE_ITEM::UpdateScore( const std::vector<std::unique_ptr<EDA_COMBINED_MATCHER>>& aMatchers,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
// aMatcher test is additive, but if we don't match the given term at all, it nulls out
|
||||
if( aMatcher )
|
||||
{
|
||||
int currentScore = aMatcher->ScoreTerms( m_SearchTerms );
|
||||
m_Score = 0;
|
||||
|
||||
// This is a hack: the second phase of search in the adapter will look for a tokenized
|
||||
// LIB_ID and send the lib part down here. While we generally want to prune ourselves
|
||||
// out here (by setting score to -1) the first time we fail to match a search term,
|
||||
// we want to give the same search term a second chance if it has been split from a library
|
||||
// name.
|
||||
if( ( m_Score >= 0 || !aLib.IsEmpty() ) && currentScore > 0 )
|
||||
m_Score += currentScore;
|
||||
else
|
||||
m_Score = -1; // Item has failed to match this term, rule it out
|
||||
}
|
||||
for( const std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : aMatchers )
|
||||
m_Score += matcher->ScoreTerms( m_SearchTerms );
|
||||
|
||||
// aFilter test is subtractive
|
||||
if( aFilter && !(*aFilter)(*this) )
|
||||
m_Score = 0;
|
||||
|
||||
// show all nodes if no search/filter/etc. criteria are given
|
||||
if( !aMatcher && aLib.IsEmpty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
if( aMatchers.empty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
m_Score = 1;
|
||||
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
child->UpdateScore( aMatcher, aLib, aFilter );
|
||||
child->UpdateScore( aMatchers, aFilter );
|
||||
}
|
||||
|
||||
|
||||
@@ -296,52 +285,29 @@ LIB_TREE_NODE_ITEM& LIB_TREE_NODE_LIBRARY::AddItem( LIB_TREE_ITEM* aItem )
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_NODE_LIBRARY::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
void LIB_TREE_NODE_LIBRARY::UpdateScore( const std::vector<std::unique_ptr<EDA_COMBINED_MATCHER>>& aMatchers,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
int maxChildScore = 0;
|
||||
|
||||
// children are additive
|
||||
if( !m_Children.empty() )
|
||||
if( m_Children.empty() )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : aMatchers )
|
||||
m_Score += matcher->ScoreTerms( m_SearchTerms );
|
||||
}
|
||||
else
|
||||
{
|
||||
int maxChildScore = 0;
|
||||
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
{
|
||||
child->UpdateScore( aMatcher, aLib, aFilter );
|
||||
child->UpdateScore( aMatchers, aFilter );
|
||||
maxChildScore = std::max( maxChildScore, child->m_Score );
|
||||
}
|
||||
|
||||
m_Score = std::max( m_Score, maxChildScore );
|
||||
}
|
||||
|
||||
// aLib test is additive
|
||||
if( !aLib.IsEmpty() && m_Name.Lower().Matches( aLib ) )
|
||||
m_Score += 1;
|
||||
|
||||
// aMatcher test is additive
|
||||
if( aMatcher )
|
||||
{
|
||||
int ownScore = aMatcher->ScoreTerms( m_SearchTerms );
|
||||
m_Score += ownScore;
|
||||
|
||||
// If we have a hit on a library, show all children in that library that pass the filter
|
||||
if( maxChildScore <= 0 && ownScore > 0 )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
{
|
||||
if( !aFilter || (*aFilter)( *this ) )
|
||||
child->ForceScore( 1 );
|
||||
|
||||
maxChildScore = std::max( maxChildScore, child->m_Score );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all children are excluded for one reason or another, drop the library from the list
|
||||
if( !m_Children.empty() && maxChildScore <= 0 )
|
||||
m_Score = 0;
|
||||
|
||||
// show all nodes if no search/filter/etc. criteria are given
|
||||
if( m_Children.empty() && !aMatcher && aLib.IsEmpty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
if( m_Children.empty() && aMatchers.empty() && ( !aFilter || (*aFilter)(*this) ) )
|
||||
m_Score = 1;
|
||||
}
|
||||
|
||||
@@ -383,10 +349,10 @@ void LIB_TREE_NODE_ROOT::Clear()
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_NODE_ROOT::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
|
||||
void LIB_TREE_NODE_ROOT::UpdateScore( const std::vector<std::unique_ptr<EDA_COMBINED_MATCHER>>& aMatchers,
|
||||
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
|
||||
child->UpdateScore( aMatcher, aLib, aFilter );
|
||||
child->UpdateScore( aMatchers, aFilter );
|
||||
}
|
||||
|
||||
|
||||
@@ -292,34 +292,16 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
// the search box.
|
||||
constexpr int MAX_TERMS = 100;
|
||||
|
||||
wxStringTokenizer tokenizer( aSearch );
|
||||
int termCount = 0;
|
||||
wxStringTokenizer tokenizer( aSearch );
|
||||
std::vector<std::unique_ptr<EDA_COMBINED_MATCHER>> termMatchers;
|
||||
|
||||
while( tokenizer.HasMoreTokens() && termCount < MAX_TERMS )
|
||||
while( tokenizer.HasMoreTokens() && termMatchers.size() < MAX_TERMS )
|
||||
{
|
||||
// First search for the full token, in case it appears in a search string
|
||||
wxString term = tokenizer.GetNextToken().Lower();
|
||||
EDA_COMBINED_MATCHER termMatcher( term, CTX_LIBITEM );
|
||||
|
||||
m_tree.UpdateScore( &termMatcher, wxEmptyString, m_filter );
|
||||
termCount++;
|
||||
|
||||
if( term.Contains( ":" ) )
|
||||
{
|
||||
// Next search for the library:item_name
|
||||
wxString lib = term.BeforeFirst( ':' );
|
||||
wxString itemName = term.AfterFirst( ':' );
|
||||
EDA_COMBINED_MATCHER itemNameMatcher( itemName, CTX_LIBITEM );
|
||||
|
||||
m_tree.UpdateScore( &itemNameMatcher, lib, m_filter );
|
||||
}
|
||||
wxString term = tokenizer.GetNextToken().Lower();
|
||||
termMatchers.emplace_back( std::make_unique<EDA_COMBINED_MATCHER>( term, CTX_LIBITEM ) );
|
||||
}
|
||||
|
||||
if( termCount == 0 )
|
||||
{
|
||||
// No terms processed; just run the filter
|
||||
m_tree.UpdateScore( nullptr, wxEmptyString, m_filter );
|
||||
}
|
||||
m_tree.UpdateScore( termMatchers, m_filter );
|
||||
|
||||
m_tree.SortNodes( m_sort_mode == BEST_MATCH );
|
||||
AfterReset();
|
||||
|
||||
+67
-43
@@ -544,23 +544,23 @@ PCB_LAYER_ID LSET::ExtractLayer() const
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::FrontAssembly()
|
||||
const LSET& LSET::FrontAssembly()
|
||||
{
|
||||
static const LSET saved( { F_SilkS, F_Mask, F_Fab, F_CrtYd } );
|
||||
static LSET saved( { F_SilkS, F_Mask, F_Fab, F_CrtYd } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::BackAssembly()
|
||||
const LSET& LSET::BackAssembly()
|
||||
{
|
||||
static const LSET saved( { B_SilkS, B_Mask, B_Fab, B_CrtYd } );
|
||||
static LSET saved( { B_SilkS, B_Mask, B_Fab, B_CrtYd } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::InternalCuMask()
|
||||
const LSET& LSET::InternalCuMask()
|
||||
{
|
||||
static const LSET saved( { In1_Cu, In2_Cu, In3_Cu, In4_Cu, In5_Cu, In6_Cu,
|
||||
static LSET saved( { In1_Cu, In2_Cu, In3_Cu, In4_Cu, In5_Cu, In6_Cu,
|
||||
In7_Cu, In8_Cu, In9_Cu, In10_Cu, In11_Cu, In12_Cu,
|
||||
In13_Cu, In14_Cu, In15_Cu, In16_Cu, In17_Cu, In18_Cu,
|
||||
In19_Cu, In20_Cu, In21_Cu, In22_Cu, In23_Cu, In24_Cu,
|
||||
@@ -569,7 +569,7 @@ LSET LSET::InternalCuMask()
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllCuMask( int aCuLayerCount )
|
||||
LSET allCuMask( int aCuLayerCount )
|
||||
{
|
||||
LSET ret;
|
||||
|
||||
@@ -580,84 +580,109 @@ LSET LSET::AllCuMask( int aCuLayerCount )
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllCuMask( int aCuLayerCount )
|
||||
{
|
||||
static LSET savedMax = allCuMask( MAX_CU_LAYERS );
|
||||
static LSET cache;
|
||||
static int cacheCuLayerCount = -1;
|
||||
|
||||
if( aCuLayerCount == MAX_CU_LAYERS )
|
||||
return savedMax;
|
||||
|
||||
if( aCuLayerCount != cacheCuLayerCount )
|
||||
{
|
||||
cache = allCuMask( aCuLayerCount );
|
||||
cacheCuLayerCount = aCuLayerCount;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
LSET allNonCuMask()
|
||||
{
|
||||
LSET mask = LSET().set();
|
||||
|
||||
for( auto it = mask.copper_layers_begin(); it != mask.copper_layers_end(); ++it )
|
||||
mask.reset( *it );
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllNonCuMask()
|
||||
{
|
||||
LSET saved = LSET().set();
|
||||
|
||||
for( auto it = saved.copper_layers_begin(); it != saved.copper_layers_end(); ++it )
|
||||
saved.reset( *it );
|
||||
|
||||
static LSET saved = allNonCuMask();
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::ExternalCuMask()
|
||||
const LSET& LSET::ExternalCuMask()
|
||||
{
|
||||
static const LSET saved( { F_Cu, B_Cu } );
|
||||
static LSET saved( { F_Cu, B_Cu } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllLayersMask()
|
||||
const LSET& LSET::AllLayersMask()
|
||||
{
|
||||
static const LSET saved = LSET().set();
|
||||
static LSET saved = LSET().set();
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::BackTechMask()
|
||||
const LSET& LSET::BackTechMask()
|
||||
{
|
||||
static const LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab } );
|
||||
static LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::BackBoardTechMask()
|
||||
const LSET& LSET::BackBoardTechMask()
|
||||
{
|
||||
static const LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste } );
|
||||
static LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::FrontTechMask()
|
||||
const LSET& LSET::FrontTechMask()
|
||||
{
|
||||
static const LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab } );
|
||||
static LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::FrontBoardTechMask()
|
||||
const LSET& LSET::FrontBoardTechMask()
|
||||
{
|
||||
static const LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste } );
|
||||
static LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllTechMask()
|
||||
const LSET& LSET::AllTechMask()
|
||||
{
|
||||
static const LSET saved = BackTechMask() | FrontTechMask();
|
||||
static LSET saved = BackTechMask() | FrontTechMask();
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::AllBoardTechMask()
|
||||
const LSET& LSET::AllBoardTechMask()
|
||||
{
|
||||
static const LSET saved = BackBoardTechMask() | FrontBoardTechMask();
|
||||
static LSET saved = BackBoardTechMask() | FrontBoardTechMask();
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::UserMask()
|
||||
const LSET& LSET::UserMask()
|
||||
{
|
||||
static const LSET saved( { Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, Margin } );
|
||||
|
||||
static LSET saved( { Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, Margin } );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::PhysicalLayersMask()
|
||||
const LSET& LSET::PhysicalLayersMask()
|
||||
{
|
||||
static const LSET saved = AllBoardTechMask() | AllCuMask();
|
||||
static LSET saved = AllBoardTechMask() | AllCuMask();
|
||||
return saved;
|
||||
}
|
||||
|
||||
@@ -680,31 +705,30 @@ LSET LSET::UserDefinedLayersMask( int aUserDefinedLayerCount )
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::FrontMask()
|
||||
const LSET& LSET::FrontMask()
|
||||
{
|
||||
static const LSET saved = FrontTechMask().set( F_Cu );
|
||||
static LSET saved = LSET( FrontTechMask() ).set( F_Cu );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::BackMask()
|
||||
const LSET& LSET::BackMask()
|
||||
{
|
||||
static const LSET saved = BackTechMask().set( B_Cu );
|
||||
static LSET saved = LSET( BackTechMask() ).set( B_Cu );
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::SideSpecificMask()
|
||||
const LSET& LSET::SideSpecificMask()
|
||||
{
|
||||
static const LSET saved = BackTechMask() | FrontTechMask() | AllCuMask();
|
||||
static LSET saved = BackTechMask() | FrontTechMask() | AllCuMask();
|
||||
return saved;
|
||||
}
|
||||
|
||||
|
||||
LSET LSET::ForbiddenFootprintLayers()
|
||||
const LSET& LSET::ForbiddenFootprintLayers()
|
||||
{
|
||||
static LSET saved = InternalCuMask();
|
||||
saved.set( In1_Cu, false );
|
||||
static LSET saved = LSET( InternalCuMask() ).set( In1_Cu, false );
|
||||
return saved;
|
||||
}
|
||||
|
||||
@@ -789,7 +813,7 @@ GAL_SET GAL_SET::DefaultVisible()
|
||||
LAYER_DRAW_BITMAPS,
|
||||
LAYER_PADS,
|
||||
LAYER_ZONES,
|
||||
LAYER_SHAPES,
|
||||
LAYER_FILLED_SHAPES,
|
||||
LAYER_LOCKED_ITEM_SHADOW,
|
||||
LAYER_CONFLICTS_SHADOW
|
||||
};
|
||||
|
||||
+9
-11
@@ -374,23 +374,21 @@ void PGM_BASE::sentryPrompt()
|
||||
if( !IsGUI() )
|
||||
return;
|
||||
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
KIPLATFORM::POLICY::PBOOL policyState = KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
|
||||
if( policyState == KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED
|
||||
&& !m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
|
||||
&& !m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
|
||||
{
|
||||
wxMessageDialog optIn = wxMessageDialog(
|
||||
nullptr,
|
||||
_( "KiCad can anonymously report crashes and special event "
|
||||
"data to developers in order to aid identifying critical bugs "
|
||||
"across the user base more effectively and help profile "
|
||||
"functionality to guide improvements. \n"
|
||||
"If you choose to voluntarily participate, KiCad will automatically "
|
||||
"handle sending said reports when crashes or events occur. \n"
|
||||
"Your design files such as schematic or PCB are not shared in this process." ),
|
||||
_( "Data collection opt in request" ), wxYES_NO | wxCENTRE );
|
||||
_( "KiCad can anonymously report crashes and special event data to developers in order to "
|
||||
"aid identifying critical bugs and help profile functionality to guide improvements. \n"
|
||||
"If you choose to voluntarily participate, KiCad will automatically send said reports "
|
||||
"when crashes or events occur. \n"
|
||||
"Your design files such as schematic and PCB are not shared in this process." ),
|
||||
_( "Data Collection Opt In" ), wxYES_NO | wxCENTRE );
|
||||
|
||||
optIn.SetYesNoLabels( _( "Opt In" ), _( "Decline" ) );
|
||||
int result = optIn.ShowModal();
|
||||
|
||||
if( result == wxID_YES )
|
||||
|
||||
@@ -678,6 +678,10 @@ void PDF_PLOTTER::StartPage( const wxString& aPageNumber, const wxString& aPageN
|
||||
m_paperSize.x *= 10.0 / m_iuPerDeviceUnit;
|
||||
m_paperSize.y *= 10.0 / m_iuPerDeviceUnit;
|
||||
|
||||
// Set m_currentPenWidth to a unused value to ensure the pen width
|
||||
// will be initialized to a the right value in pdf file by the first item to plot
|
||||
m_currentPenWidth = 0;
|
||||
|
||||
// Open the content stream; the page object will go later
|
||||
m_pageStreamHandle = startPdfStream();
|
||||
|
||||
@@ -1304,8 +1308,8 @@ bool PDF_PLOTTER::EndPlot()
|
||||
|
||||
for( const auto& [ linkHandle, linkPair ] : m_hyperlinkHandles )
|
||||
{
|
||||
const BOX2D& box = linkPair.first;
|
||||
const wxString& url = linkPair.second;
|
||||
BOX2D box = linkPair.first;
|
||||
wxString url = linkPair.second;
|
||||
|
||||
startPdfObject( linkHandle );
|
||||
|
||||
@@ -1345,6 +1349,9 @@ bool PDF_PLOTTER::EndPlot()
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_project )
|
||||
url = ResolveUriByEnvVars( url, m_project );
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"/A << /Type /Action /S /URI /URI %s >>\n"
|
||||
">>\n",
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <project/net_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <string_utils.h>
|
||||
#include <base_units.h>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
// const int netSettingsSchemaVersion = 0;
|
||||
@@ -692,7 +693,7 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
return cacheItr->second;
|
||||
|
||||
// No cache found - build a vector of all netclasses assigned to or matching this net
|
||||
std::vector<std::shared_ptr<NETCLASS>> resolvedNetclasses;
|
||||
std::unordered_set<std::shared_ptr<NETCLASS>> resolvedNetclasses;
|
||||
|
||||
// First find explicit netclass assignments
|
||||
auto it = m_netClassLabelAssignments.find( aNetName );
|
||||
@@ -705,12 +706,11 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
|
||||
if( netclass )
|
||||
{
|
||||
resolvedNetclasses.push_back( std::move( netclass ) );
|
||||
resolvedNetclasses.insert( std::move( netclass ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedNetclasses.push_back(
|
||||
getOrAddImplicitNetcless( netclassName ) );
|
||||
resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -724,11 +724,11 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
|
||||
if( netclass )
|
||||
{
|
||||
resolvedNetclasses.push_back( std::move( netclass ) );
|
||||
resolvedNetclasses.insert( std::move( netclass ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedNetclasses.push_back( getOrAddImplicitNetcless( netclassName ) );
|
||||
resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -746,7 +746,7 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
// will also sort resolvedNetclasses by priority order.
|
||||
std::vector<NETCLASS*> netclassPtrs;
|
||||
|
||||
for( std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
|
||||
for( const std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
|
||||
netclassPtrs.push_back( nc.get() );
|
||||
|
||||
wxString name;
|
||||
@@ -757,8 +757,8 @@ std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aN
|
||||
if( netclassPtrs.size() == 1 )
|
||||
{
|
||||
// No defaults were added - just return the primary netclass
|
||||
m_effectiveNetclassCache[aNetName] = resolvedNetclasses[0];
|
||||
return resolvedNetclasses[0];
|
||||
m_effectiveNetclassCache[aNetName] = *resolvedNetclasses.begin();
|
||||
return *resolvedNetclasses.begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+139
-182
@@ -21,6 +21,7 @@
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/fs_zip.h>
|
||||
#include <wx/regex.h>
|
||||
#include <wx/uri.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/zipstrm.h>
|
||||
@@ -43,33 +44,13 @@
|
||||
class PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER : public wxDirTraverser
|
||||
{
|
||||
public:
|
||||
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER( const std::string& aExtRegex, const wxString& aPrjDir, wxZipOutputStream& aZipFileOutput,
|
||||
REPORTER& aReporter, bool aVerbose ) :
|
||||
m_zipFile( aZipFileOutput ),
|
||||
m_prjDir( aPrjDir ),
|
||||
m_fileExtRegex( aExtRegex, std::regex_constants::ECMAScript | std::regex_constants::icase ),
|
||||
m_reporter( aReporter ),
|
||||
m_errorOccurred( false ),
|
||||
m_verbose( aVerbose )
|
||||
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER( const wxString& aPrjDir ) :
|
||||
m_prjDir( aPrjDir )
|
||||
{}
|
||||
|
||||
virtual wxDirTraverseResult OnFile( const wxString& aFilename ) override
|
||||
{
|
||||
if( std::regex_search( aFilename.ToStdString(), m_fileExtRegex ) )
|
||||
{
|
||||
addFileToZip( aFilename );
|
||||
|
||||
// Special processing for IBIS files to include the corresponding pkg file
|
||||
if( aFilename.EndsWith( FILEEXT::IbisFileExtension ) )
|
||||
{
|
||||
wxFileName package( aFilename );
|
||||
package.MakeRelativeTo( m_prjDir );
|
||||
package.SetExt( wxS( "pkg" ) );
|
||||
|
||||
if( package.Exists() )
|
||||
addFileToZip( package.GetFullPath() );
|
||||
}
|
||||
}
|
||||
m_files.emplace_back( aFilename );
|
||||
|
||||
return wxDIR_CONTINUE;
|
||||
}
|
||||
@@ -79,76 +60,22 @@ public:
|
||||
return wxDIR_CONTINUE;
|
||||
}
|
||||
|
||||
unsigned long GetUncompressedBytes() const
|
||||
const std::vector<wxString>& GetFilesToArchive() const
|
||||
{
|
||||
return m_uncompressedBytes;
|
||||
}
|
||||
|
||||
bool GetErrorOccurred() const
|
||||
{
|
||||
return m_errorOccurred;
|
||||
return m_files;
|
||||
}
|
||||
|
||||
private:
|
||||
void addFileToZip( const wxString& aFilename)
|
||||
{
|
||||
wxString msg;
|
||||
wxFileSystem fsfile;
|
||||
|
||||
wxFileName curr_fn( aFilename );
|
||||
curr_fn.MakeRelativeTo( m_prjDir );
|
||||
|
||||
wxString currFilename = curr_fn.GetFullPath();
|
||||
|
||||
// Read input file and add it to the zip file:
|
||||
wxFSFile* infile = fsfile.OpenFile( currFilename );
|
||||
|
||||
if( infile )
|
||||
{
|
||||
m_zipFile.PutNextEntry( currFilename, infile->GetModificationTime() );
|
||||
infile->GetStream()->Read( m_zipFile );
|
||||
m_zipFile.CloseEntry();
|
||||
|
||||
m_uncompressedBytes += infile->GetStream()->GetSize();
|
||||
|
||||
if( m_verbose )
|
||||
{
|
||||
msg.Printf( _( "Archived file '%s'." ), currFilename );
|
||||
m_reporter.Report( msg, RPT_SEVERITY_INFO );
|
||||
}
|
||||
|
||||
delete infile;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_verbose )
|
||||
{
|
||||
msg.Printf( _( "Failed to archive file '%s'." ), currFilename );
|
||||
m_reporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
m_errorOccurred = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
wxZipOutputStream& m_zipFile;
|
||||
|
||||
wxString m_prjDir;
|
||||
std::regex m_fileExtRegex;
|
||||
REPORTER& m_reporter;
|
||||
|
||||
bool m_errorOccurred; // True if an error archiving the file
|
||||
bool m_verbose; // True to enable verbose logging
|
||||
|
||||
// Keep track of how many bytes would have been used without compression
|
||||
unsigned long m_uncompressedBytes = 0;
|
||||
wxString m_prjDir;
|
||||
std::vector<wxString> m_files;
|
||||
};
|
||||
|
||||
|
||||
PROJECT_ARCHIVER::PROJECT_ARCHIVER()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PROJECT_ARCHIVER::AreZipArchivesIdentical( const wxString& aZipFileA,
|
||||
const wxString& aZipFileB, REPORTER& aReporter )
|
||||
{
|
||||
@@ -238,6 +165,7 @@ bool PROJECT_ARCHIVER::Unarchive( const wxString& aSrcFile, const wxString& aDes
|
||||
// Now let's set the filetimes based on what's in the zip
|
||||
wxFileName outputFileName( fullname );
|
||||
wxDateTime fileTime = entry->GetDateTime();
|
||||
|
||||
// For now we set access, mod, create to the same datetime
|
||||
// create (third arg) is only used on Windows
|
||||
outputFileName.SetTimes( &fileTime, &fileTime, &fileTime );
|
||||
@@ -252,74 +180,68 @@ bool PROJECT_ARCHIVER::Archive( const wxString& aSrcDir, const wxString& aDestFi
|
||||
REPORTER& aReporter, bool aVerbose, bool aIncludeExtraFiles )
|
||||
{
|
||||
|
||||
#define EXT( ext ) "\\." + ext + "|"
|
||||
#define NAME( name ) name + "|"
|
||||
#define EXT_NO_PIPE( ext ) "\\." + ext
|
||||
#define NAME_NO_PIPE( name ) name
|
||||
std::set<wxString> extensions;
|
||||
std::set<wxString> files; // File names without extensions such as fp-lib-table.
|
||||
|
||||
// List of file extensions that are always archived
|
||||
std::string fileExtensionRegex = "("
|
||||
EXT( FILEEXT::ProjectFileExtension )
|
||||
EXT( FILEEXT::ProjectLocalSettingsFileExtension )
|
||||
EXT( FILEEXT::KiCadSchematicFileExtension )
|
||||
EXT( FILEEXT::KiCadSymbolLibFileExtension )
|
||||
EXT( FILEEXT::KiCadPcbFileExtension )
|
||||
EXT( FILEEXT::KiCadFootprintFileExtension )
|
||||
EXT( FILEEXT::DesignRulesFileExtension )
|
||||
EXT( FILEEXT::DrawingSheetFileExtension )
|
||||
EXT( FILEEXT::KiCadJobSetFileExtension )
|
||||
EXT( FILEEXT::JsonFileExtension ) // for design blocks
|
||||
EXT( FILEEXT::WorkbookFileExtension ) +
|
||||
NAME( FILEEXT::FootprintLibraryTableFileName ) +
|
||||
NAME( FILEEXT::SymbolLibraryTableFileName ) +
|
||||
NAME_NO_PIPE( FILEEXT::DesignBlockLibraryTableFileName );
|
||||
extensions.emplace( FILEEXT::ProjectFileExtension );
|
||||
extensions.emplace( FILEEXT::ProjectLocalSettingsFileExtension );
|
||||
extensions.emplace( FILEEXT::KiCadSchematicFileExtension );
|
||||
extensions.emplace( FILEEXT::KiCadSymbolLibFileExtension );
|
||||
extensions.emplace( FILEEXT::KiCadPcbFileExtension );
|
||||
extensions.emplace( FILEEXT::KiCadFootprintFileExtension );
|
||||
extensions.emplace( FILEEXT::DesignRulesFileExtension );
|
||||
extensions.emplace( FILEEXT::DrawingSheetFileExtension );
|
||||
extensions.emplace( FILEEXT::KiCadJobSetFileExtension );
|
||||
extensions.emplace( FILEEXT::JsonFileExtension ); // for design blocks
|
||||
extensions.emplace( FILEEXT::WorkbookFileExtension );
|
||||
|
||||
files.emplace( FILEEXT::FootprintLibraryTableFileName );
|
||||
files.emplace( FILEEXT::SymbolLibraryTableFileName );
|
||||
files.emplace( FILEEXT::DesignBlockLibraryTableFileName );
|
||||
|
||||
// List of additional file extensions that are only archived when aIncludeExtraFiles is true
|
||||
if( aIncludeExtraFiles )
|
||||
{
|
||||
fileExtensionRegex += "|"
|
||||
EXT( FILEEXT::LegacyProjectFileExtension )
|
||||
EXT( FILEEXT::LegacySchematicFileExtension )
|
||||
EXT( FILEEXT::LegacySymbolLibFileExtension )
|
||||
EXT( FILEEXT::LegacySymbolDocumentFileExtension )
|
||||
EXT( FILEEXT::FootprintAssignmentFileExtension )
|
||||
EXT( FILEEXT::LegacyPcbFileExtension )
|
||||
EXT( FILEEXT::LegacyFootprintLibPathExtension )
|
||||
EXT( FILEEXT::StepFileAbrvExtension ) // 3d files
|
||||
EXT( FILEEXT::StepFileExtension ) // 3d files
|
||||
EXT( FILEEXT::VrmlFileExtension ) // 3d files
|
||||
EXT( FILEEXT::GerberFileExtensionsRegex ) // Gerber files (g?, g??, .gm12 (from protel export))
|
||||
EXT( FILEEXT::GerberJobFileExtension ) // Gerber job files
|
||||
EXT( FILEEXT::FootprintPlaceFileExtension ) // Our position files
|
||||
EXT( FILEEXT::DrillFileExtension ) // Fab drill files
|
||||
EXT( "nc" ) // Fab drill files
|
||||
EXT( "xnc" ) // Fab drill files
|
||||
EXT( FILEEXT::IpcD356FileExtension )
|
||||
EXT( FILEEXT::ReportFileExtension )
|
||||
EXT( FILEEXT::NetlistFileExtension )
|
||||
EXT( FILEEXT::PythonFileExtension )
|
||||
EXT( FILEEXT::PdfFileExtension )
|
||||
EXT( FILEEXT::TextFileExtension )
|
||||
EXT( FILEEXT::SpiceFileExtension ) // SPICE files
|
||||
EXT( FILEEXT::SpiceSubcircuitFileExtension ) // SPICE files
|
||||
EXT( FILEEXT::SpiceModelFileExtension ) // SPICE files
|
||||
EXT_NO_PIPE( FILEEXT::IbisFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacyProjectFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacySchematicFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacySymbolLibFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacySymbolDocumentFileExtension );
|
||||
extensions.emplace( FILEEXT::FootprintAssignmentFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacyPcbFileExtension );
|
||||
extensions.emplace( FILEEXT::LegacyFootprintLibPathExtension );
|
||||
extensions.emplace( FILEEXT::StepFileAbrvExtension );
|
||||
extensions.emplace( FILEEXT::StepFileExtension ); // 3d files
|
||||
extensions.emplace( FILEEXT::VrmlFileExtension ); // 3d files
|
||||
extensions.emplace( FILEEXT::GerberJobFileExtension ); // Gerber job files
|
||||
extensions.emplace( FILEEXT::FootprintPlaceFileExtension ); // Our position files
|
||||
extensions.emplace( FILEEXT::DrillFileExtension ); // Fab drill files
|
||||
extensions.emplace( "nc" ); // Fab drill files
|
||||
extensions.emplace( "xnc" ); // Fab drill files
|
||||
extensions.emplace( FILEEXT::IpcD356FileExtension );
|
||||
extensions.emplace( FILEEXT::ReportFileExtension );
|
||||
extensions.emplace( FILEEXT::NetlistFileExtension );
|
||||
extensions.emplace( FILEEXT::PythonFileExtension );
|
||||
extensions.emplace( FILEEXT::PdfFileExtension );
|
||||
extensions.emplace( FILEEXT::TextFileExtension );
|
||||
extensions.emplace( FILEEXT::SpiceFileExtension ); // SPICE files
|
||||
extensions.emplace( FILEEXT::SpiceSubcircuitFileExtension ); // SPICE files
|
||||
extensions.emplace( FILEEXT::SpiceModelFileExtension ); // SPICE files
|
||||
extensions.emplace( FILEEXT::IbisFileExtension );
|
||||
extensions.emplace( "pkg" );
|
||||
extensions.emplace( FILEEXT::GencadFileExtension );
|
||||
}
|
||||
|
||||
fileExtensionRegex += ")";
|
||||
|
||||
#undef EXT
|
||||
#undef NAME
|
||||
#undef EXT_NO_PIPE
|
||||
#undef NAME_NO_PIPE
|
||||
// Gerber files (g?, g??, .gm12 (from protel export)).
|
||||
wxRegEx gerberFiles( FILEEXT::GerberFileExtensionsRegex );
|
||||
wxASSERT( gerberFiles.IsValid() );
|
||||
|
||||
bool success = true;
|
||||
wxString msg;
|
||||
wxString oldCwd = wxGetCwd();
|
||||
|
||||
wxFileName sourceDir( aSrcDir );
|
||||
wxFileName sourceDir( aSrcDir, wxEmptyString, wxEmptyString );
|
||||
|
||||
wxSetWorkingDirectory( sourceDir.GetFullPath() );
|
||||
wxSetWorkingDirectory( aSrcDir );
|
||||
|
||||
wxFFileOutputStream ostream( aDestFile );
|
||||
|
||||
@@ -334,7 +256,6 @@ bool PROJECT_ARCHIVER::Archive( const wxString& aSrcDir, const wxString& aDestFi
|
||||
|
||||
wxDir projectDir( aSrcDir );
|
||||
wxString currFilename;
|
||||
wxArrayString files;
|
||||
|
||||
if( !projectDir.IsOpened() )
|
||||
{
|
||||
@@ -348,58 +269,94 @@ bool PROJECT_ARCHIVER::Archive( const wxString& aSrcDir, const wxString& aDestFi
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
size_t uncompressedBytes = 0;
|
||||
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER traverser( aSrcDir );
|
||||
|
||||
projectDir.Traverse( traverser );
|
||||
|
||||
for( const wxString& fileName : traverser.GetFilesToArchive() )
|
||||
{
|
||||
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER traverser( fileExtensionRegex, aSrcDir, zipstream,
|
||||
aReporter, aVerbose );
|
||||
wxFileName fn( fileName );
|
||||
wxString extLower = fn.GetExt().Lower();
|
||||
wxString fileNameLower = fn.GetName().Lower();
|
||||
bool archive = false;
|
||||
|
||||
projectDir.Traverse( traverser );
|
||||
|
||||
success = !traverser.GetErrorOccurred();
|
||||
|
||||
auto reportSize =
|
||||
[]( unsigned long aSize ) -> wxString
|
||||
{
|
||||
constexpr float KB = 1024.0;
|
||||
constexpr float MB = KB * 1024.0;
|
||||
|
||||
if( aSize >= MB )
|
||||
return wxString::Format( wxT( "%0.2f MB" ), aSize / MB );
|
||||
else if( aSize >= KB )
|
||||
return wxString::Format( wxT( "%0.2f KB" ), aSize / KB );
|
||||
else
|
||||
return wxString::Format( wxT( "%lu bytes" ), aSize );
|
||||
};
|
||||
|
||||
size_t zipBytesCnt = ostream.GetSize();
|
||||
unsigned long uncompressedBytes = traverser.GetUncompressedBytes();
|
||||
|
||||
if( zipstream.Close() )
|
||||
if( !extLower.IsEmpty() )
|
||||
{
|
||||
msg.Printf( _( "Zip archive '%s' created (%s uncompressed, %s compressed)." ),
|
||||
aDestFile,
|
||||
reportSize( uncompressedBytes ),
|
||||
reportSize( zipBytesCnt ) );
|
||||
aReporter.Report( msg, RPT_SEVERITY_INFO );
|
||||
if( ( extensions.find( extLower ) != extensions.end() )
|
||||
|| ( aIncludeExtraFiles && gerberFiles.Matches( extLower ) ) )
|
||||
archive = true;
|
||||
}
|
||||
else if( !fileNameLower.IsEmpty() && ( files.find( fileNameLower ) != files.end() ) )
|
||||
{
|
||||
archive = true;
|
||||
}
|
||||
|
||||
if( !archive )
|
||||
continue;
|
||||
|
||||
wxFileSystem fsFile;
|
||||
fn.MakeRelativeTo( aSrcDir );
|
||||
|
||||
wxString relativeFn = fn.GetFullPath();
|
||||
|
||||
// Read input file and add it to the zip file:
|
||||
wxFSFile* infile = fsFile.OpenFile( relativeFn );
|
||||
|
||||
if( infile )
|
||||
{
|
||||
zipstream.PutNextEntry( relativeFn, infile->GetModificationTime() );
|
||||
infile->GetStream()->Read( zipstream );
|
||||
zipstream.CloseEntry();
|
||||
|
||||
uncompressedBytes += infile->GetStream()->GetSize();
|
||||
|
||||
if( aVerbose )
|
||||
{
|
||||
msg.Printf( _( "Archived file '%s'." ), relativeFn );
|
||||
aReporter.Report( msg, RPT_SEVERITY_INFO );
|
||||
}
|
||||
|
||||
delete infile;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( wxT( "Failed to create file '%s'." ), aDestFile );
|
||||
aReporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
success = false;
|
||||
if( aVerbose )
|
||||
{
|
||||
msg.Printf( _( "Failed to archive file '%s'." ), relativeFn );
|
||||
aReporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( const std::regex_error& e )
|
||||
|
||||
auto reportSize =
|
||||
[]( size_t aSize ) -> wxString
|
||||
{
|
||||
constexpr float KB = 1024.0;
|
||||
constexpr float MB = KB * 1024.0;
|
||||
|
||||
if( aSize >= MB )
|
||||
return wxString::Format( wxT( "%0.2f MB" ), aSize / MB );
|
||||
else if( aSize >= KB )
|
||||
return wxString::Format( wxT( "%0.2f KB" ), aSize / KB );
|
||||
else
|
||||
return wxString::Format( wxT( "%zu bytes" ), aSize );
|
||||
};
|
||||
|
||||
size_t zipBytesCnt = ostream.GetSize();
|
||||
|
||||
if( zipstream.Close() )
|
||||
{
|
||||
// Something bad happened here with the regex
|
||||
wxASSERT_MSG( false, e.what() );
|
||||
|
||||
if( aVerbose )
|
||||
{
|
||||
msg.Printf( _( "Error: '%s'." ), e.what() );
|
||||
aReporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
msg.Printf( _( "Zip archive '%s' created (%s uncompressed, %s compressed)." ),
|
||||
aDestFile,
|
||||
reportSize( uncompressedBytes ),
|
||||
reportSize( zipBytesCnt ) );
|
||||
aReporter.Report( msg, RPT_SEVERITY_INFO );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( wxT( "Failed to create file '%s'." ), aDestFile );
|
||||
aReporter.Report( msg, RPT_SEVERITY_ERROR );
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -433,14 +433,14 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
||||
registerMigration( 3, 4,
|
||||
[&]()
|
||||
{
|
||||
// Schema version 3 to 4: LAYER_SHAPES added to visibility controls
|
||||
// Schema version 3 to 4: LAYER_FILLED_SHAPES added to visibility controls
|
||||
|
||||
std::string ptr( "board.visible_items" );
|
||||
|
||||
if( Contains( ptr ) )
|
||||
{
|
||||
if( At( ptr ).is_array() )
|
||||
At( ptr ).push_back( LAYER_SHAPES - GAL_LAYER_ID_START );
|
||||
At( ptr ).push_back( LAYER_FILLED_SHAPES - GAL_LAYER_ID_START );
|
||||
else
|
||||
At( "board" ).erase( "visible_items" );
|
||||
|
||||
|
||||
+14
-30
@@ -53,15 +53,10 @@ REPORTER& REPORTER::Report( const char* aText, SEVERITY aSeverity )
|
||||
}
|
||||
|
||||
|
||||
bool REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
wxFAIL_MSG( "HasMessageOfSeverity is not implemented in this reporter" );
|
||||
return HasMessage();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
|
||||
wxCHECK_MSG( m_textCtrl != nullptr, *this,
|
||||
wxT( "No wxTextCtrl object defined in WX_TEXT_CTRL_REPORTER." ) );
|
||||
|
||||
@@ -78,7 +73,8 @@ bool WX_TEXT_CTRL_REPORTER::HasMessage() const
|
||||
|
||||
REPORTER& WX_STRING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
m_severityMask |= aSeverity;
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
|
||||
m_string << aText << wxS( "\n" );
|
||||
return *this;
|
||||
}
|
||||
@@ -92,7 +88,7 @@ const wxString& WX_STRING_REPORTER::GetMessages() const
|
||||
|
||||
void WX_STRING_REPORTER::Clear()
|
||||
{
|
||||
m_severityMask = 0;
|
||||
REPORTER::Clear();
|
||||
m_string.clear();
|
||||
}
|
||||
|
||||
@@ -103,15 +99,9 @@ bool WX_STRING_REPORTER::HasMessage() const
|
||||
}
|
||||
|
||||
|
||||
bool WX_STRING_REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
return ( m_severityMask & aSeverityMask ) != 0;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
return *this;
|
||||
return REPORTER::Report( aText, aSeverity );
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +118,8 @@ REPORTER& NULL_REPORTER::GetInstance()
|
||||
|
||||
REPORTER& CLI_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aMsg, aSeverity );
|
||||
|
||||
FILE* target = stdout;
|
||||
|
||||
if( aSeverity == RPT_SEVERITY_ERROR )
|
||||
@@ -138,24 +130,10 @@ REPORTER& CLI_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
|
||||
else
|
||||
wxFprintf( target, aMsg + wxS( "\n" ) );
|
||||
|
||||
m_hasMessageMap[aSeverity] = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool CLI_REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
for( const auto& [severity, flag] : m_hasMessageMap )
|
||||
{
|
||||
if( ( aSeverityMask & severity ) > 0 && flag )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& CLI_REPORTER::GetInstance()
|
||||
{
|
||||
static CLI_REPORTER s_cliReporter;
|
||||
@@ -166,6 +144,8 @@ REPORTER& CLI_REPORTER::GetInstance()
|
||||
|
||||
REPORTER& STDOUT_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aMsg, aSeverity );
|
||||
|
||||
switch( aSeverity )
|
||||
{
|
||||
case RPT_SEVERITY_UNDEFINED: std::cout << "SEVERITY_UNDEFINED: "; break;
|
||||
@@ -197,6 +177,8 @@ REPORTER& STDOUT_REPORTER::GetInstance()
|
||||
|
||||
REPORTER& WXLOG_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aMsg, aSeverity );
|
||||
|
||||
switch( aSeverity )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: wxLogError( aMsg ); break;
|
||||
@@ -227,6 +209,8 @@ REPORTER& WXLOG_REPORTER::GetInstance()
|
||||
|
||||
REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
|
||||
if( m_statusBar )
|
||||
m_statusBar->SetStatusText( aText, m_position );
|
||||
|
||||
|
||||
+26
-29
@@ -34,6 +34,7 @@
|
||||
#include <io/kicad/kicad_io_utils.h>
|
||||
|
||||
#include <wx/translation.h>
|
||||
#include <wx/ffile.h>
|
||||
|
||||
|
||||
// Fall back to getc() when getc_unlocked() is not available on the target platform.
|
||||
@@ -94,40 +95,36 @@ std::string StrPrintf( const char* format, ... )
|
||||
|
||||
wxString SafeReadFile( const wxString& aFilePath, const wxString& aReadType )
|
||||
{
|
||||
auto From_UTF8_WINE =
|
||||
[]( const char* cstring )
|
||||
{
|
||||
wxString line = wxString::FromUTF8( cstring );
|
||||
wxString contents;
|
||||
wxFFile ff( aFilePath );
|
||||
|
||||
if( line.IsEmpty() ) // happens when cstring is not a valid UTF8 sequence
|
||||
line = wxConvCurrent->cMB2WC( cstring ); // try to use locale conversion
|
||||
|
||||
// We have trouble here *probably* because Wine-hosted LTSpice writes out MSW
|
||||
// encoded text on a macOS, where it isn't expected. In any case, wxWidgets'
|
||||
// wxSafeConvert() appears to get around it.
|
||||
|
||||
if( line.IsEmpty() )
|
||||
line = wxSafeConvertMB2WX( cstring );
|
||||
|
||||
// I'm not sure what the source of this style of line-endings is, but it can be
|
||||
// found in some Fairchild Semiconductor SPICE files.
|
||||
line.Replace( wxS( "\r\r\n" ), wxS( "\n" ) );
|
||||
|
||||
return line;
|
||||
};
|
||||
|
||||
// Open file
|
||||
FILE* fp = wxFopen( aFilePath, aReadType );
|
||||
|
||||
if( !fp )
|
||||
if( !ff.IsOpened() )
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'." ), aFilePath ) );
|
||||
|
||||
FILE_LINE_READER fileReader( fp, aFilePath );
|
||||
// Try to determine encoding
|
||||
char bytes[2]{ 0 };
|
||||
ff.Read( bytes, 2 );
|
||||
bool utf16le = bytes[1] == 0;
|
||||
|
||||
wxString contents;
|
||||
ff.Seek( 0 );
|
||||
|
||||
while( fileReader.ReadLine() )
|
||||
contents += From_UTF8_WINE( fileReader.Line() );
|
||||
if( utf16le )
|
||||
ff.ReadAll( &contents, wxMBConvUTF16LE() );
|
||||
else
|
||||
ff.ReadAll( &contents, wxMBConvUTF8() );
|
||||
|
||||
if( contents.empty() )
|
||||
{
|
||||
ff.Seek( 0 );
|
||||
ff.ReadAll( &contents, wxConvAuto( wxFONTENCODING_CP1252 ) );
|
||||
}
|
||||
|
||||
if( contents.empty() )
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ), aFilePath ) );
|
||||
|
||||
// I'm not sure what the source of this style of line-endings is, but it can be
|
||||
// found in some Fairchild Semiconductor SPICE files.
|
||||
contents.Replace( wxS( "\r\r\n" ), wxS( "\n" ) );
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,9 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
||||
reinterpret_cast<int*>( &m_SearchPane.selection_zoom ),
|
||||
static_cast<int>( SEARCH_PANE::SELECTION_ZOOM::PAN ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "search_pane.search_hidden_fields",
|
||||
&m_SearchPane.search_hidden_fields, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "system.first_run_shown",
|
||||
&m_System.first_run_shown, false ) ); //@todo RFB remove? - not used
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <settings/aui_settings.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/aui/framemanager.h>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <settings/bom_settings.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <core/json_serializers.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
|
||||
@@ -250,6 +250,16 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath )
|
||||
CLR( "3d_viewer.soldermask_top", LAYER_3D_SOLDERMASK_TOP );
|
||||
CLR( "3d_viewer.solderpaste", LAYER_3D_SOLDERPASTE );
|
||||
|
||||
for( int layer = LAYER_3D_USER_1; layer <= LAYER_3D_USER_45; ++layer )
|
||||
{
|
||||
int idx = layer - LAYER_3D_USER_1;
|
||||
PCB_LAYER_ID pcb_layer = Map3DLayerToPCBLayer( layer );
|
||||
|
||||
m_params.emplace_back( new COLOR_MAP_PARAM( "3d_viewer.user_" + std::to_string( idx + 1 ),
|
||||
layer, s_defaultTheme.at( pcb_layer ),
|
||||
&m_colors ) );
|
||||
}
|
||||
|
||||
registerMigration( 0, 1, std::bind( &COLOR_SETTINGS::migrateSchema0to1, this ) );
|
||||
|
||||
registerMigration( 1, 2,
|
||||
|
||||
@@ -56,6 +56,9 @@ CVPCB_SETTINGS::CVPCB_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.autozoom",
|
||||
&m_FootprintViewerAutoZoomOnSelect, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.use_45_limit",
|
||||
&m_ViewersDisplay.m_Use45Limit, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.show_pad_fill",
|
||||
&m_ViewersDisplay.m_DisplayPadFill, true ) );
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <settings/grid_settings.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <wx/translation.h>
|
||||
#include <core/json_serializers.h>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <wx/aui/framemanager.h> // ensure class wxAuiPaneInfo is defined for other includes
|
||||
|
||||
#include "settings/kicad_settings.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
#include <settings/aui_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ GAL_SET UserVisbilityLayers()
|
||||
LAYER_VIAS,
|
||||
LAYER_PADS,
|
||||
LAYER_ZONES,
|
||||
LAYER_SHAPES,
|
||||
LAYER_FILLED_SHAPES,
|
||||
LAYER_DRAW_BITMAPS,
|
||||
LAYER_FOOTPRINTS_FR,
|
||||
LAYER_FOOTPRINTS_BK,
|
||||
@@ -62,7 +62,7 @@ GAL_LAYER_ID RenderLayerFromVisibilityLayer( VISIBILITY_LAYER aLayer )
|
||||
case VISIBILITY_LAYER::VIAS: return LAYER_VIAS;
|
||||
case VISIBILITY_LAYER::PADS: return LAYER_PADS;
|
||||
case VISIBILITY_LAYER::ZONES: return LAYER_ZONES;
|
||||
case VISIBILITY_LAYER::SHAPES: return LAYER_SHAPES;
|
||||
case VISIBILITY_LAYER::SHAPES: return LAYER_FILLED_SHAPES;
|
||||
case VISIBILITY_LAYER::BITMAPS: return LAYER_DRAW_BITMAPS;
|
||||
case VISIBILITY_LAYER::FOOTPRINTS_FRONT: return LAYER_FOOTPRINTS_FR;
|
||||
case VISIBILITY_LAYER::FOOTPRINTS_BACK: return LAYER_FOOTPRINTS_BK;
|
||||
@@ -92,7 +92,7 @@ std::optional<VISIBILITY_LAYER> VisibilityLayerFromRenderLayer( GAL_LAYER_ID aLa
|
||||
case LAYER_VIAS: return VISIBILITY_LAYER::VIAS;
|
||||
case LAYER_PADS: return VISIBILITY_LAYER::PADS;
|
||||
case LAYER_ZONES: return VISIBILITY_LAYER::ZONES;
|
||||
case LAYER_SHAPES: return VISIBILITY_LAYER::SHAPES;
|
||||
case LAYER_FILLED_SHAPES: return VISIBILITY_LAYER::SHAPES;
|
||||
case LAYER_DRAW_BITMAPS: return VISIBILITY_LAYER::BITMAPS;
|
||||
case LAYER_FOOTPRINTS_FR: return VISIBILITY_LAYER::FOOTPRINTS_FRONT;
|
||||
case LAYER_FOOTPRINTS_BK: return VISIBILITY_LAYER::FOOTPRINTS_BACK;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <json_common.h>
|
||||
|
||||
#include <project/project_file.h>
|
||||
#include <settings/parameters.h>
|
||||
|
||||
@@ -1325,7 +1325,7 @@ bool SETTINGS_MANAGER::TriggerBackupIfNeeded( REPORTER& aReporter ) const
|
||||
return dt;
|
||||
};
|
||||
|
||||
wxFileName projectPath( Prj().GetProjectPath() );
|
||||
wxFileName projectPath( Prj().GetProjectPath(), wxEmptyString, wxEmptyString );
|
||||
|
||||
// Skip backup if project path isn't valid or writable
|
||||
if( !projectPath.IsOk() || !projectPath.Exists() || !projectPath.IsDirWritable() )
|
||||
|
||||
@@ -646,7 +646,7 @@ wxString RemoveHTMLTags( const wxString& aInput )
|
||||
|
||||
wxString LinkifyHTML( wxString aStr )
|
||||
{
|
||||
static wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.,:;<>\\s\u00b6])" ),
|
||||
static wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.,:;<>\\(\\)\\s\u00b6])" ),
|
||||
wxRE_ICASE );
|
||||
|
||||
regex.ReplaceAll( &aStr, "<a href=\"\\0\">\\0</a>" );
|
||||
|
||||
@@ -174,7 +174,7 @@ void STROKE_PARAMS::Stroke( const SHAPE* aShape, LINE_STYLE aLineStyle, int aWid
|
||||
|
||||
wxASSERT( startAngle < arcEndAngle );
|
||||
|
||||
EDA_ANGLE angleIncrementInRadians = EDA_ANGLE( M_PI / ANGLE_360 );
|
||||
EDA_ANGLE angleIncrement = EDA_ANGLE( 0.5, DEGREES_T );
|
||||
|
||||
for( size_t i = 0; i < 10000 && startAngle < arcEndAngle; ++i )
|
||||
{
|
||||
@@ -188,13 +188,13 @@ void STROKE_PARAMS::Stroke( const SHAPE* aShape, LINE_STYLE aLineStyle, int aWid
|
||||
|| aLineStyle == LINE_STYLE::DASH )
|
||||
{
|
||||
for( EDA_ANGLE currentAngle = startAngle; currentAngle < endAngle;
|
||||
currentAngle += angleIncrementInRadians )
|
||||
currentAngle += angleIncrement )
|
||||
{
|
||||
VECTOR2I a( center.x + KiROUND( r * currentAngle.Cos() ),
|
||||
center.y + KiROUND( r * currentAngle.Sin() ) );
|
||||
|
||||
// Calculate the next angle step, ensuring it doesn't exceed the endAngle
|
||||
EDA_ANGLE nextAngle = currentAngle + angleIncrementInRadians;
|
||||
EDA_ANGLE nextAngle = currentAngle + angleIncrement;
|
||||
|
||||
if( nextAngle > endAngle )
|
||||
{
|
||||
|
||||
@@ -931,7 +931,8 @@ TOOL_ACTION ACTIONS::gridOrigin( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.editGridOrigin" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Grid Origin..." ) )
|
||||
.Tooltip( _( "Set the grid origin point" ) ) );
|
||||
.Tooltip( _( "Set the grid origin point" ) )
|
||||
.Icon( BITMAPS::grid_select_axis ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::inchesUnits( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.imperialUnits" )
|
||||
|
||||
@@ -627,7 +627,7 @@ int COMMON_TOOLS::GridProperties( const TOOL_EVENT& aEvent )
|
||||
int COMMON_TOOLS::GridOrigin( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
VECTOR2I origin = m_frame->GetGridOrigin();
|
||||
WX_PT_ENTRY_DIALOG dlg( m_frame, _( "Grid Origin" ), _( "X:" ), _( "Y:" ), origin );
|
||||
WX_PT_ENTRY_DIALOG dlg( m_frame, _( "Grid Origin" ), _( "X:" ), _( "Y:" ), origin, true );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
@@ -679,6 +679,9 @@ int COMMON_TOOLS::TogglePolarCoords( const TOOL_EVENT& aEvent )
|
||||
|
||||
int COMMON_TOOLS::ResetLocalCoords( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( !m_frame->GetScreen() ) // Can happen in footprint chooser frame
|
||||
return 0;
|
||||
|
||||
const KIGFX::VC_SETTINGS& vcSettings = m_toolMgr->GetCurrentToolVC();
|
||||
|
||||
// Use either the active tool forced cursor position or the general settings
|
||||
|
||||
@@ -328,7 +328,7 @@ VECTOR2D TOOL_MANAGER::GetCursorPosition() const
|
||||
|
||||
|
||||
bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const ki::any& aParam,
|
||||
COMMIT* aCommit )
|
||||
COMMIT* aCommit, bool aFromAPI )
|
||||
{
|
||||
if( m_shuttingDown )
|
||||
return true;
|
||||
@@ -336,10 +336,6 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const ki:
|
||||
bool retVal = false;
|
||||
TOOL_EVENT event = aAction.MakeEvent();
|
||||
|
||||
// We initialize the SYNCHRONOUS state to finished so that tools that don't have an event
|
||||
// loop won't hang if someone forgets to set the state.
|
||||
std::atomic<SYNCRONOUS_TOOL_STATE> synchronousControl = STS_FINISHED;
|
||||
|
||||
if( event.Category() == TC_COMMAND )
|
||||
event.SetMousePosition( GetCursorPosition() );
|
||||
|
||||
@@ -347,20 +343,20 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const ki:
|
||||
if( aParam.has_value() )
|
||||
event.SetParameter( aParam );
|
||||
|
||||
// Pass the commit (if any)
|
||||
if( aCommit )
|
||||
{
|
||||
event.SetSynchronous( &synchronousControl );
|
||||
event.SetCommit( aCommit );
|
||||
}
|
||||
|
||||
if( aNow )
|
||||
{
|
||||
TOOL_STATE* current = m_activeState;
|
||||
|
||||
// An event with a commit must be run synchronously
|
||||
if( aCommit )
|
||||
{
|
||||
// An event with a commit must be run synchronously
|
||||
// We initialize the SYNCHRONOUS state to finished so that tools that don't have an
|
||||
// event loop won't hang if someone forgets to set the state.
|
||||
std::atomic<SYNCRONOUS_TOOL_STATE> synchronousControl = STS_FINISHED;
|
||||
|
||||
event.SetSynchronous( &synchronousControl );
|
||||
event.SetCommit( aCommit );
|
||||
|
||||
processEvent( event );
|
||||
|
||||
while( synchronousControl == STS_RUNNING )
|
||||
@@ -384,6 +380,17 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const ki:
|
||||
}
|
||||
else
|
||||
{
|
||||
// It is really dangerous to pass a commit (whose lifetime we can't guarantee) to
|
||||
// deferred event processing. There is a possibility that user actions will get run
|
||||
// in between, which might either affect the lifetime of the commit or push or pop
|
||||
// other commits. However, we don't currently have a better solution for the API.
|
||||
if( aCommit )
|
||||
{
|
||||
wxASSERT_MSG( aFromAPI, wxT( "Deferred actions have no way of guaranteeing the "
|
||||
"lifetime of the COMMIT object" ) );
|
||||
event.SetCommit( aCommit );
|
||||
}
|
||||
|
||||
PostEvent( event );
|
||||
}
|
||||
|
||||
|
||||
@@ -114,8 +114,6 @@ void TOOLS_HOLDER::PopTool( const TOOL_EVENT& aEvent )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wxASSERT_MSG( false, wxS( "Popped a Tool Not on the Tool Stack!" ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <widgets/footprint_preview_widget.h>
|
||||
#include <lib_id.h>
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <kiway.h>
|
||||
@@ -61,7 +62,7 @@ FOOTPRINT_PREVIEW_WIDGET::FOOTPRINT_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aK
|
||||
m_outerSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
if( m_prev_panel )
|
||||
m_outerSizer->Add( m_prev_panel->GetWindow(), 1, wxALL | wxEXPAND, 0 );
|
||||
m_outerSizer->Add( m_prev_panel->GetCanvas(), 1, wxALL | wxEXPAND, 0 );
|
||||
|
||||
m_outerSizer->Add( m_statusPanel, 1, wxALL | wxEXPAND, 0 );
|
||||
|
||||
@@ -77,7 +78,7 @@ void FOOTPRINT_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
|
||||
m_statusPanel->Show();
|
||||
|
||||
if( m_prev_panel )
|
||||
m_prev_panel->GetWindow()->Hide();
|
||||
m_prev_panel->GetCanvas()->Hide();
|
||||
|
||||
Layout();
|
||||
}
|
||||
@@ -89,7 +90,7 @@ void FOOTPRINT_PREVIEW_WIDGET::ClearStatus()
|
||||
m_statusPanel->Hide();
|
||||
|
||||
if( m_prev_panel )
|
||||
m_prev_panel->GetWindow()->Show();
|
||||
m_prev_panel->GetCanvas()->Show();
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "widgets/ui_common.h"
|
||||
#include <widgets/grid_checkbox.h>
|
||||
#include <wx/renderer.h>
|
||||
|
||||
|
||||
//-------- Renderer ---------------------------------------------------------------------
|
||||
//
|
||||
// Augments wxGridBoolRenderer to support indeterminate state
|
||||
|
||||
// ------------ This section copied verbatim from wxwidgets/src/generic/grid.cpp (which
|
||||
// is sadly private)
|
||||
|
||||
// the space between the cell edge and the checkbox mark
|
||||
const int GRID_CELL_CHECKBOX_MARGIN = 2;
|
||||
|
||||
wxRect
|
||||
wxGetContentRect(wxSize contentSize,
|
||||
const wxRect& cellRect,
|
||||
int hAlign,
|
||||
int vAlign)
|
||||
{
|
||||
// Keep square aspect ratio for the checkbox, but ensure that it fits into
|
||||
// the available space, even if it's smaller than the standard size.
|
||||
const wxCoord minSize = wxMin(cellRect.width, cellRect.height);
|
||||
if ( contentSize.x >= minSize || contentSize.y >= minSize )
|
||||
{
|
||||
// It must still have positive size, however.
|
||||
const int fittingSize = wxMax(1, minSize - 2*GRID_CELL_CHECKBOX_MARGIN);
|
||||
|
||||
contentSize.x =
|
||||
contentSize.y = fittingSize;
|
||||
}
|
||||
|
||||
wxRect contentRect(contentSize);
|
||||
|
||||
if ( hAlign & wxALIGN_CENTER_HORIZONTAL )
|
||||
{
|
||||
contentRect = contentRect.CentreIn(cellRect, wxHORIZONTAL);
|
||||
}
|
||||
else if ( hAlign & wxALIGN_RIGHT )
|
||||
{
|
||||
contentRect.SetX(cellRect.x + cellRect.width
|
||||
- contentSize.x - GRID_CELL_CHECKBOX_MARGIN);
|
||||
}
|
||||
else // ( hAlign == wxALIGN_LEFT ) and invalid alignment value
|
||||
{
|
||||
contentRect.SetX(cellRect.x + GRID_CELL_CHECKBOX_MARGIN);
|
||||
}
|
||||
|
||||
if ( vAlign & wxALIGN_CENTER_VERTICAL )
|
||||
{
|
||||
contentRect = contentRect.CentreIn(cellRect, wxVERTICAL);
|
||||
}
|
||||
else if ( vAlign & wxALIGN_BOTTOM )
|
||||
{
|
||||
contentRect.SetY(cellRect.y + cellRect.height
|
||||
- contentSize.y - GRID_CELL_CHECKBOX_MARGIN);
|
||||
}
|
||||
else // wxALIGN_TOP
|
||||
{
|
||||
contentRect.SetY(cellRect.y + GRID_CELL_CHECKBOX_MARGIN);
|
||||
}
|
||||
|
||||
return contentRect;
|
||||
}
|
||||
|
||||
// ------------ End copied section
|
||||
|
||||
// ------------ This section copied from wxwidgets/src/generic/gridctrl.cpp, with changes
|
||||
// noted
|
||||
|
||||
void GRID_CELL_CHECKBOX_RENDERER::Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected)
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
||||
|
||||
int hAlign = wxALIGN_LEFT;
|
||||
int vAlign = wxALIGN_CENTRE_VERTICAL;
|
||||
attr.GetNonDefaultAlignment(&hAlign, &vAlign);
|
||||
|
||||
const wxRect checkBoxRect =
|
||||
wxGetContentRect(GetBestSize(grid, attr, dc, row, col),
|
||||
rect, hAlign, vAlign);
|
||||
|
||||
bool value;
|
||||
if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
|
||||
{
|
||||
value = grid.GetTable()->GetValueAsBool(row, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString cellval( grid.GetTable()->GetValue(row, col) );
|
||||
value = wxGridCellBoolEditor::IsTrueValue(cellval);
|
||||
}
|
||||
|
||||
int flags = wxCONTROL_CELL;
|
||||
#if 1 // KiCad change
|
||||
if( grid.GetTable()->GetValue( row, col ) == INDETERMINATE_STATE )
|
||||
flags |= wxCONTROL_UNDETERMINED;
|
||||
else
|
||||
#endif
|
||||
if (value)
|
||||
flags |= wxCONTROL_CHECKED;
|
||||
|
||||
wxRendererNative::Get().DrawCheckBox( &grid, dc, checkBoxRect, flags );
|
||||
}
|
||||
|
||||
// ------------ End copied section
|
||||
|
||||
|
||||
|
||||
//-------- Editor -----------------------------------------------------------------------
|
||||
//
|
||||
// None required; interactivity delegated to GRID_TRICKS.
|
||||
|
||||
|
||||
@@ -331,12 +331,12 @@ class TEXT_BUTTON_URL : public wxComboCtrl
|
||||
{
|
||||
public:
|
||||
TEXT_BUTTON_URL( wxWindow* aParent, DIALOG_SHIM* aParentDlg, SEARCH_STACK* aSearchStack,
|
||||
EMBEDDED_FILES* aFiles ) :
|
||||
std::vector<EMBEDDED_FILES*> aFilesStack ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
|
||||
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
|
||||
m_dlg( aParentDlg ),
|
||||
m_searchStack( aSearchStack ),
|
||||
m_files( aFiles )
|
||||
m_filesStack( aFilesStack )
|
||||
{
|
||||
UpdateButtonBitmaps();
|
||||
|
||||
@@ -381,7 +381,7 @@ protected:
|
||||
|
||||
if( customize.GetEmbed() )
|
||||
{
|
||||
EMBEDDED_FILES::EMBEDDED_FILE* result = m_files->AddFile( fn, false );
|
||||
EMBEDDED_FILES::EMBEDDED_FILE* result = m_filesStack[0]->AddFile( fn, false );
|
||||
SetValue( result->GetLink() );
|
||||
}
|
||||
else
|
||||
@@ -392,7 +392,7 @@ protected:
|
||||
}
|
||||
else
|
||||
{
|
||||
GetAssociatedDocument( m_dlg, GetValue(), &m_dlg->Prj(), m_searchStack, m_files );
|
||||
GetAssociatedDocument( m_dlg, GetValue(), &m_dlg->Prj(), m_searchStack, m_filesStack );
|
||||
}
|
||||
|
||||
m_dlg->CleanupAfterModalSubDialog();
|
||||
@@ -413,15 +413,15 @@ protected:
|
||||
}
|
||||
|
||||
protected:
|
||||
DIALOG_SHIM* m_dlg;
|
||||
SEARCH_STACK* m_searchStack;
|
||||
EMBEDDED_FILES* m_files;
|
||||
DIALOG_SHIM* m_dlg;
|
||||
SEARCH_STACK* m_searchStack;
|
||||
std::vector<EMBEDDED_FILES*> m_filesStack;
|
||||
};
|
||||
|
||||
|
||||
void GRID_CELL_URL_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
|
||||
{
|
||||
m_control = new TEXT_BUTTON_URL( aParent, m_dlg, m_searchStack, m_files );
|
||||
m_control = new TEXT_BUTTON_URL( aParent, m_dlg, m_searchStack, m_filesStack );
|
||||
WX_GRID::CellEditorSetMargins( Combo() );
|
||||
|
||||
#if wxUSE_VALIDATORS
|
||||
|
||||
@@ -47,8 +47,8 @@ void GRID_CELL_TEXT_EDITOR::StartingKey( wxKeyEvent& event )
|
||||
{
|
||||
if( m_validator )
|
||||
{
|
||||
m_validator.get()->SetWindow( Text() );
|
||||
m_validator.get()->ProcessEvent( event );
|
||||
m_validator->SetWindow( Text() );
|
||||
m_validator->ProcessEvent( event );
|
||||
}
|
||||
|
||||
if( event.GetSkipped() )
|
||||
@@ -66,9 +66,12 @@ void GRID_CELL_TEXT_EDITOR::SetSize( const wxRect& aRect )
|
||||
|
||||
#if defined( __WXMSW__ )
|
||||
rect.Offset( 0, 1 );
|
||||
#elif defined( __WXMAC__ )
|
||||
rect.Offset( 0, 2 );
|
||||
rect.SetHeight( rect.GetHeight() - 4 );
|
||||
#endif
|
||||
|
||||
wxGridCellEditor::SetSize( rect );
|
||||
wxGridCellEditor::SetSize( rect ); // NOLINT(*-parent-virtual-call)
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +129,9 @@ void GRID_CELL_STC_EDITOR::SetSize( const wxRect& aRect )
|
||||
rect.Offset( -1, 1 );
|
||||
#elif defined( __WXGTK__ )
|
||||
rect.Offset( -1, 3 );
|
||||
#else
|
||||
rect.Offset( 1, 3 );
|
||||
rect.SetHeight( rect.GetHeight() - 6 );
|
||||
#endif
|
||||
|
||||
wxGridCellEditor::SetSize( rect );
|
||||
@@ -155,7 +161,7 @@ void GRID_CELL_STC_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandl
|
||||
stc_ctrl()->SetScrollWidthTracking( true );
|
||||
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS(
|
||||
stc_ctrl(), wxEmptyString, true,
|
||||
stc_ctrl(), wxEmptyString, false,
|
||||
|
||||
// onAcceptFn
|
||||
[this]( wxKeyEvent& aEvent )
|
||||
|
||||
@@ -42,6 +42,7 @@ extern APIIMPORT wxPGGlobalVarsClass* wxPGGlobalVars;
|
||||
|
||||
PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame ) :
|
||||
wxPanel( aParent ),
|
||||
m_SuppressGridChangeEvents( 0 ),
|
||||
m_frame( aFrame ),
|
||||
m_splitter_key_proportion( -1 )
|
||||
{
|
||||
@@ -168,8 +169,29 @@ void PROPERTIES_PANEL::OnLanguageChanged( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
class SUPPRESS_GRID_CHANGED_EVENTS
|
||||
{
|
||||
public:
|
||||
SUPPRESS_GRID_CHANGED_EVENTS( PROPERTIES_PANEL* aPanel ) :
|
||||
m_panel( aPanel )
|
||||
{
|
||||
m_panel->m_SuppressGridChangeEvents++;
|
||||
}
|
||||
|
||||
~SUPPRESS_GRID_CHANGED_EVENTS()
|
||||
{
|
||||
m_panel->m_SuppressGridChangeEvents--;
|
||||
}
|
||||
|
||||
private:
|
||||
PROPERTIES_PANEL* m_panel;
|
||||
};
|
||||
|
||||
|
||||
void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
{
|
||||
SUPPRESS_GRID_CHANGED_EVENTS raii( this );
|
||||
|
||||
auto reset =
|
||||
[&]()
|
||||
{
|
||||
@@ -369,7 +391,13 @@ bool PROPERTIES_PANEL::getItemValue( EDA_ITEM* aItem, PROPERTY_BASE* aProperty,
|
||||
converted = any.GetAs( &aValue );
|
||||
|
||||
if( !converted )
|
||||
wxFAIL_MSG( wxS( "Could not convert wxAny to wxVariant" ) );
|
||||
{
|
||||
wxString propName = aProperty->Name();
|
||||
propName.Replace( ' ', '_' );
|
||||
wxFAIL_MSG( wxString::Format( wxS( "Could not convert wxAny to wxVariant for %s::%s" ),
|
||||
aItem->GetClass(),
|
||||
propName ) );
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
@@ -434,12 +462,17 @@ void PROPERTIES_PANEL::onShow( wxShowEvent& aEvent )
|
||||
|
||||
void PROPERTIES_PANEL::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() && m_grid->IsAnyModified() )
|
||||
// m_grid->IsAnyModified() doesn't work for the first modification
|
||||
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
|
||||
{
|
||||
wxVariant oldValue = m_grid->GetSelectedProperty()->GetValue();
|
||||
|
||||
m_grid->CommitChangesFromEditor();
|
||||
|
||||
// Pass the tab key on so the default property grid tab behavior is honored.
|
||||
aEvent.Skip();
|
||||
// If there was no change, treat it as a navigation key
|
||||
if( oldValue == m_grid->GetSelectedProperty()->GetValue() )
|
||||
aEvent.Skip();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,11 +104,14 @@ protected:
|
||||
bool extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable );
|
||||
|
||||
public:
|
||||
int m_SuppressGridChangeEvents;
|
||||
|
||||
protected:
|
||||
std::vector<PROPERTY_BASE*> m_displayed;
|
||||
wxPropertyGrid* m_grid;
|
||||
EDA_BASE_FRAME* m_frame;
|
||||
wxStaticText* m_caption;
|
||||
wxPropertyGrid* m_grid;
|
||||
EDA_BASE_FRAME* m_frame;
|
||||
wxStaticText* m_caption;
|
||||
|
||||
/// Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
|
||||
float m_splitter_key_proportion;
|
||||
|
||||
@@ -29,22 +29,28 @@
|
||||
#include <widgets/std_bitmap_button.h>
|
||||
|
||||
|
||||
#define ID_TOGGLE_ZOOM_TO_SELECTION 14000
|
||||
#define ID_TOGGLE_PAN_TO_SELECTION 14001
|
||||
#define ID_TOGGLE_ZOOM_TO_SELECTION 14000
|
||||
#define ID_TOGGLE_PAN_TO_SELECTION 14001
|
||||
#define ID_TOGGLE_SEARCH_HIDDEN_FIELDS 14002
|
||||
|
||||
|
||||
class SEARCH_PANE_MENU : public ACTION_MENU
|
||||
{
|
||||
public:
|
||||
SEARCH_PANE_MENU( EDA_DRAW_FRAME& aFrame ) :
|
||||
SEARCH_PANE_MENU( SEARCH_PANE* aSearchPane, EDA_DRAW_FRAME& aFrame ) :
|
||||
ACTION_MENU( true, nullptr ),
|
||||
m_frame( aFrame )
|
||||
m_frame( aFrame ),
|
||||
m_searchPane( aSearchPane )
|
||||
{
|
||||
Add( _( "Zoom to Selection" ), _( "Toggle zooming to selections in the search pane" ),
|
||||
ID_TOGGLE_ZOOM_TO_SELECTION, BITMAPS::zoom_fit_to_objects, true );
|
||||
Add( _( "Pan to Selection" ), _( "Toggle panning to selections in the search pane" ),
|
||||
ID_TOGGLE_PAN_TO_SELECTION, BITMAPS::zoom_center_on_screen, true );
|
||||
|
||||
AppendSeparator();
|
||||
Add( _( "Search Hidden Fields" ), wxEmptyString,
|
||||
ID_TOGGLE_SEARCH_HIDDEN_FIELDS, BITMAPS::invisible_text, true );
|
||||
|
||||
updateZoomPanCheckboxes();
|
||||
}
|
||||
|
||||
@@ -57,18 +63,24 @@ public:
|
||||
switch( id )
|
||||
{
|
||||
case ID_TOGGLE_ZOOM_TO_SELECTION:
|
||||
settings.selection_zoom =
|
||||
item->IsChecked() ? APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::ZOOM
|
||||
: APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::NONE;
|
||||
settings.selection_zoom = item->IsChecked() ? APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::ZOOM
|
||||
: APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::NONE;
|
||||
updateZoomPanCheckboxes();
|
||||
break;
|
||||
|
||||
case ID_TOGGLE_PAN_TO_SELECTION:
|
||||
settings.selection_zoom =
|
||||
item->IsChecked() ? APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::PAN
|
||||
: APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::NONE;
|
||||
settings.selection_zoom = item->IsChecked() ? APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::PAN
|
||||
: APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::NONE;
|
||||
updateZoomPanCheckboxes();
|
||||
break;
|
||||
|
||||
case ID_TOGGLE_SEARCH_HIDDEN_FIELDS:
|
||||
settings.search_hidden_fields = item->IsChecked();
|
||||
updateZoomPanCheckboxes();
|
||||
m_searchPane->RefreshSearch();
|
||||
break;
|
||||
}
|
||||
|
||||
return OPT_TOOL_EVENT();
|
||||
}
|
||||
|
||||
@@ -79,25 +91,26 @@ private:
|
||||
|
||||
wxMenuItem* zoomCb = FindItem( ID_TOGGLE_ZOOM_TO_SELECTION );
|
||||
wxMenuItem* panCb = FindItem( ID_TOGGLE_PAN_TO_SELECTION );
|
||||
wxMenuItem* hiddenFieldsCb = FindItem( ID_TOGGLE_SEARCH_HIDDEN_FIELDS );
|
||||
|
||||
zoomCb->Check( settings.selection_zoom
|
||||
== APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::ZOOM );
|
||||
panCb->Check( settings.selection_zoom
|
||||
== APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::PAN );
|
||||
zoomCb->Check( settings.selection_zoom == APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::ZOOM );
|
||||
panCb->Check( settings.selection_zoom == APP_SETTINGS_BASE::SEARCH_PANE::SELECTION_ZOOM::PAN );
|
||||
hiddenFieldsCb->Check( settings.search_hidden_fields );
|
||||
}
|
||||
|
||||
private:
|
||||
EDA_DRAW_FRAME& m_frame;
|
||||
SEARCH_PANE* m_searchPane;
|
||||
};
|
||||
|
||||
|
||||
SEARCH_PANE::SEARCH_PANE( EDA_DRAW_FRAME* aFrame ) :
|
||||
SEARCH_PANE_BASE( aFrame ),
|
||||
m_frame( aFrame )
|
||||
SEARCH_PANE_BASE( aFrame ),
|
||||
m_frame( aFrame )
|
||||
{
|
||||
m_frame->Bind( EDA_LANG_CHANGED, &SEARCH_PANE::OnLanguageChange, this );
|
||||
|
||||
m_menu = new SEARCH_PANE_MENU( *m_frame );
|
||||
m_menu = new SEARCH_PANE_MENU( this, *m_frame );
|
||||
|
||||
m_menuButton->SetBitmap( KiBitmapBundle( BITMAPS::config ) );
|
||||
m_menuButton->Bind( wxEVT_LEFT_DOWN,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user