You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

444 lines
15 KiB

9 years ago
9 years ago
9 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2014-2017 CERN
  5. * @author Maciej Suminski <maciej.suminski@cern.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include "pcb_draw_panel_gal.h"
  25. #include <view/view.h>
  26. #include <view/wx_view_controls.h>
  27. #include <pcb_painter.h>
  28. #include <worksheet_viewitem.h>
  29. #include <ratsnest_viewitem.h>
  30. #include <ratsnest_data.h>
  31. #include <connectivity.h>
  32. #include <class_colors_design_settings.h>
  33. #include <class_board.h>
  34. #include <class_module.h>
  35. #include <class_track.h>
  36. #include <wxBasePcbFrame.h>
  37. #include <gal/graphics_abstraction_layer.h>
  38. #include <functional>
  39. using namespace std::placeholders;
  40. const LAYER_NUM GAL_LAYER_ORDER[] =
  41. {
  42. LAYER_GP_OVERLAY,
  43. LAYER_DRC,
  44. LAYER_PADS_NETNAMES, LAYER_VIAS_NETNAMES,
  45. Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts,
  46. LAYER_MOD_TEXT_FR,
  47. LAYER_MOD_REFERENCES, LAYER_MOD_VALUES,
  48. LAYER_RATSNEST, LAYER_ANCHOR,
  49. LAYER_VIAS_HOLES, LAYER_PADS_HOLES, LAYER_NON_PLATED,
  50. LAYER_VIA_THROUGH, LAYER_VIA_BBLIND,
  51. LAYER_VIA_MICROVIA, LAYER_PADS,
  52. LAYER_PAD_FR_NETNAMES, LAYER_PAD_FR,
  53. NETNAMES_LAYER_INDEX( F_Cu ), F_Cu, F_Mask, F_SilkS, F_Paste, F_Adhes,
  54. NETNAMES_LAYER_INDEX( In1_Cu ), In1_Cu,
  55. NETNAMES_LAYER_INDEX( In2_Cu ), In2_Cu,
  56. NETNAMES_LAYER_INDEX( In3_Cu ), In3_Cu,
  57. NETNAMES_LAYER_INDEX( In4_Cu ), In4_Cu,
  58. NETNAMES_LAYER_INDEX( In5_Cu ), In5_Cu,
  59. NETNAMES_LAYER_INDEX( In6_Cu ), In6_Cu,
  60. NETNAMES_LAYER_INDEX( In7_Cu ), In7_Cu,
  61. NETNAMES_LAYER_INDEX( In8_Cu ), In8_Cu,
  62. NETNAMES_LAYER_INDEX( In9_Cu ), In9_Cu,
  63. NETNAMES_LAYER_INDEX( In10_Cu ), In10_Cu,
  64. NETNAMES_LAYER_INDEX( In11_Cu ), In11_Cu,
  65. NETNAMES_LAYER_INDEX( In12_Cu ), In12_Cu,
  66. NETNAMES_LAYER_INDEX( In13_Cu ), In13_Cu,
  67. NETNAMES_LAYER_INDEX( In14_Cu ), In14_Cu,
  68. NETNAMES_LAYER_INDEX( In15_Cu ), In15_Cu,
  69. NETNAMES_LAYER_INDEX( In16_Cu ), In16_Cu,
  70. NETNAMES_LAYER_INDEX( In17_Cu ), In17_Cu,
  71. NETNAMES_LAYER_INDEX( In18_Cu ), In18_Cu,
  72. NETNAMES_LAYER_INDEX( In19_Cu ), In19_Cu,
  73. NETNAMES_LAYER_INDEX( In20_Cu ), In20_Cu,
  74. NETNAMES_LAYER_INDEX( In21_Cu ), In21_Cu,
  75. NETNAMES_LAYER_INDEX( In22_Cu ), In22_Cu,
  76. NETNAMES_LAYER_INDEX( In23_Cu ), In23_Cu,
  77. NETNAMES_LAYER_INDEX( In24_Cu ), In24_Cu,
  78. NETNAMES_LAYER_INDEX( In25_Cu ), In25_Cu,
  79. NETNAMES_LAYER_INDEX( In26_Cu ), In26_Cu,
  80. NETNAMES_LAYER_INDEX( In27_Cu ), In27_Cu,
  81. NETNAMES_LAYER_INDEX( In28_Cu ), In28_Cu,
  82. NETNAMES_LAYER_INDEX( In29_Cu ), In29_Cu,
  83. NETNAMES_LAYER_INDEX( In30_Cu ), In30_Cu,
  84. LAYER_PAD_BK_NETNAMES, LAYER_PAD_BK,
  85. NETNAMES_LAYER_INDEX( B_Cu ), B_Cu, B_Mask, B_Adhes, B_Paste, B_SilkS,
  86. LAYER_MOD_TEXT_BK,
  87. LAYER_WORKSHEET
  88. };
  89. PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
  90. const wxPoint& aPosition, const wxSize& aSize,
  91. KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
  92. EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
  93. {
  94. setDefaultLayerOrder();
  95. setDefaultLayerDeps();
  96. m_painter.reset( new KIGFX::PCB_PAINTER( m_gal ) );
  97. m_view->SetPainter( m_painter.get() );
  98. // Load display options (such as filled/outline display of items).
  99. // Can be made only if the parent window is an EDA_DRAW_FRAME (or a derived class)
  100. // which is not always the case (namely when it is used from a wxDialog like the pad editor)
  101. EDA_DRAW_FRAME* frame = GetParentEDAFrame();
  102. if( frame )
  103. {
  104. auto displ_opts = (PCB_DISPLAY_OPTIONS*) frame->GetDisplayOptions();
  105. static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
  106. }
  107. }
  108. PCB_DRAW_PANEL_GAL::~PCB_DRAW_PANEL_GAL()
  109. {
  110. }
  111. void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard )
  112. {
  113. m_view->Clear();
  114. // Load zones
  115. for( int i = 0; i < aBoard->GetAreaCount(); ++i )
  116. m_view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) );
  117. // Load drawings
  118. for( auto drawing : const_cast<BOARD*>(aBoard)->Drawings() )
  119. m_view->Add( drawing );
  120. // Load tracks
  121. for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
  122. m_view->Add( track );
  123. // Load modules and its additional elements
  124. for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
  125. {
  126. module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, m_view, _1, -1 ) );
  127. m_view->Add( module );
  128. }
  129. // Segzones (equivalent of ZONE_CONTAINER for legacy boards)
  130. for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
  131. m_view->Add( zone );
  132. // Ratsnest
  133. m_ratsnest.reset( new KIGFX::RATSNEST_VIEWITEM( aBoard->GetConnectivity() ) );
  134. m_view->Add( m_ratsnest.get() );
  135. }
  136. void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet )
  137. {
  138. m_worksheet.reset( aWorksheet );
  139. m_view->Add( m_worksheet.get() );
  140. }
  141. void PCB_DRAW_PANEL_GAL::UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings )
  142. {
  143. KIGFX::PCB_RENDER_SETTINGS* rs;
  144. rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
  145. rs->ImportLegacyColors( aSettings );
  146. m_gal->SetCursorColor( aSettings->GetItemColor( LAYER_CURSOR ) );
  147. }
  148. void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer )
  149. {
  150. // Set display settings for high contrast mode
  151. KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings();
  152. SetTopLayer( aLayer );
  153. rSettings->ClearActiveLayers();
  154. rSettings->SetActiveLayer( aLayer );
  155. if( IsCopperLayer( aLayer ) )
  156. {
  157. // Bring some other layers to the front in case of copper layers and make them colored
  158. // fixme do not like the idea of storing the list of layers here,
  159. // should be done in some other way I guess..
  160. LAYER_NUM layers[] = {
  161. GetNetnameLayer( aLayer ),
  162. LAYER_VIA_THROUGH, LAYER_VIAS_HOLES, LAYER_VIAS_NETNAMES,
  163. LAYER_PADS, LAYER_PADS_HOLES, LAYER_PADS_NETNAMES,
  164. LAYER_NON_PLATED, LAYER_GP_OVERLAY, LAYER_RATSNEST
  165. };
  166. for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
  167. rSettings->SetActiveLayer( layers[i] );
  168. // Pads should be shown too
  169. if( aLayer == B_Cu )
  170. {
  171. rSettings->SetActiveLayer( LAYER_PAD_BK );
  172. rSettings->SetActiveLayer( LAYER_MOD_BK );
  173. rSettings->SetActiveLayer( LAYER_PAD_BK_NETNAMES );
  174. }
  175. else if( aLayer == F_Cu )
  176. {
  177. rSettings->SetActiveLayer( LAYER_PAD_FR );
  178. rSettings->SetActiveLayer( LAYER_MOD_FR );
  179. rSettings->SetActiveLayer( LAYER_PAD_FR_NETNAMES );
  180. }
  181. }
  182. m_view->UpdateAllLayersColor();
  183. }
  184. void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer )
  185. {
  186. m_view->ClearTopLayers();
  187. setDefaultLayerOrder();
  188. m_view->SetTopLayer( aLayer );
  189. // Layers that should always have on-top attribute enabled
  190. const LAYER_NUM layers[] = {
  191. LAYER_VIA_THROUGH, LAYER_VIAS_HOLES, LAYER_VIAS_NETNAMES,
  192. LAYER_PADS, LAYER_PADS_HOLES, LAYER_PADS_NETNAMES,
  193. LAYER_NON_PLATED, LAYER_GP_OVERLAY, LAYER_RATSNEST,
  194. LAYER_DRC
  195. };
  196. for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
  197. m_view->SetTopLayer( layers[i] );
  198. // Extra layers that are brought to the top if a F.* or B.* is selected
  199. const LAYER_NUM frontLayers[] = {
  200. F_Cu, F_Adhes, F_Paste, F_SilkS, F_Mask, F_CrtYd, F_Fab, LAYER_PAD_FR,
  201. LAYER_PAD_FR_NETNAMES, NETNAMES_LAYER_INDEX( F_Cu ), -1
  202. };
  203. const LAYER_NUM backLayers[] = {
  204. B_Cu, B_Adhes, B_Paste, B_SilkS, B_Mask, B_CrtYd, B_Fab, LAYER_PAD_BK,
  205. LAYER_PAD_BK_NETNAMES, NETNAMES_LAYER_INDEX( B_Cu ), -1
  206. };
  207. const LAYER_NUM* extraLayers = NULL;
  208. // Bring a few more extra layers to the top depending on the selected board side
  209. if( IsFrontLayer( aLayer ) )
  210. extraLayers = frontLayers;
  211. else if( IsBackLayer( aLayer ) )
  212. extraLayers = backLayers;
  213. if( extraLayers )
  214. {
  215. const LAYER_NUM* l = extraLayers;
  216. while( *l >= 0 )
  217. m_view->SetTopLayer( *l++ );
  218. // Move the active layer to the top
  219. if( !IsCopperLayer( aLayer ) )
  220. m_view->SetLayerOrder( aLayer, m_view->GetLayerOrder( GAL_LAYER_ORDER[0] ) );
  221. }
  222. else if( IsCopperLayer( aLayer ) )
  223. {
  224. // Display labels for copper layers on the top
  225. m_view->SetTopLayer( GetNetnameLayer( aLayer ) );
  226. }
  227. m_view->UpdateAllLayersOrder();
  228. }
  229. void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard )
  230. {
  231. // Load layer & elements visibility settings
  232. for( LAYER_NUM i = 0; i < PCB_LAYER_ID_COUNT; ++i )
  233. {
  234. m_view->SetLayerVisible( i, aBoard->IsLayerVisible( PCB_LAYER_ID( i ) ) );
  235. // Synchronize netname layers as well
  236. if( IsCopperLayer( i ) )
  237. m_view->SetLayerVisible( GetNetnameLayer( i ), aBoard->IsLayerVisible( PCB_LAYER_ID( i ) ) );
  238. }
  239. for( GAL_LAYER_ID i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; ++i )
  240. {
  241. m_view->SetLayerVisible( i, aBoard->IsElementVisible( i ) );
  242. }
  243. // Enable some layers that are GAL specific
  244. m_view->SetLayerVisible( LAYER_PADS_HOLES, true );
  245. m_view->SetLayerVisible( LAYER_VIAS_HOLES, true );
  246. m_view->SetLayerVisible( LAYER_WORKSHEET, true );
  247. m_view->SetLayerVisible( LAYER_GP_OVERLAY, true );
  248. }
  249. void PCB_DRAW_PANEL_GAL::GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList )
  250. {
  251. BOARD* board = static_cast<PCB_BASE_FRAME*>( m_parent )->GetBoard();
  252. wxString txt;
  253. int viasCount = 0;
  254. int trackSegmentsCount = 0;
  255. for( const BOARD_ITEM* item = board->m_Track; item; item = item->Next() )
  256. {
  257. if( item->Type() == PCB_VIA_T )
  258. viasCount++;
  259. else
  260. trackSegmentsCount++;
  261. }
  262. txt.Printf( wxT( "%d" ), board->GetPadCount() );
  263. aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) );
  264. txt.Printf( wxT( "%d" ), viasCount );
  265. aList.push_back( MSG_PANEL_ITEM( _( "Vias" ), txt, DARKGREEN ) );
  266. txt.Printf( wxT( "%d" ), trackSegmentsCount );
  267. aList.push_back( MSG_PANEL_ITEM( _( "Track Segments" ), txt, DARKGREEN ) );
  268. txt.Printf( wxT( "%d" ), board->GetNodesCount() );
  269. aList.push_back( MSG_PANEL_ITEM( _( "Nodes" ), txt, DARKCYAN ) );
  270. txt.Printf( wxT( "%d" ), board->GetNetCount() );
  271. aList.push_back( MSG_PANEL_ITEM( _( "Nets" ), txt, RED ) );
  272. txt.Printf( wxT( "%d" ), board->GetConnectivity()->GetUnconnectedCount() );
  273. aList.push_back( MSG_PANEL_ITEM( _( "Unconnected" ), txt, BLUE ) );
  274. }
  275. void PCB_DRAW_PANEL_GAL::OnShow()
  276. {
  277. PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParent() );
  278. if( frame )
  279. {
  280. SetTopLayer( frame->GetActiveLayer() );
  281. PCB_DISPLAY_OPTIONS* displ_opts = (PCB_DISPLAY_OPTIONS*) frame->GetDisplayOptions();
  282. static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
  283. m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
  284. }
  285. m_view->RecacheAllItems();
  286. }
  287. void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
  288. {
  289. for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
  290. {
  291. LAYER_NUM layer = GAL_LAYER_ORDER[i];
  292. wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
  293. m_view->SetLayerOrder( layer, i );
  294. }
  295. }
  296. bool PCB_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
  297. {
  298. bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
  299. setDefaultLayerDeps();
  300. return rv;
  301. }
  302. void PCB_DRAW_PANEL_GAL::RedrawRatsnest()
  303. {
  304. if( m_ratsnest )
  305. m_view->Update( m_ratsnest.get() );
  306. }
  307. void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
  308. {
  309. // caching makes no sense for Cairo and other software renderers
  310. auto target = m_backend == GAL_TYPE_OPENGL ? KIGFX::TARGET_CACHED : KIGFX::TARGET_NONCACHED;
  311. for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
  312. m_view->SetLayerTarget( i, target );
  313. for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
  314. {
  315. LAYER_NUM layer = GAL_LAYER_ORDER[i];
  316. wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
  317. // Set layer display dependencies & targets
  318. if( IsCopperLayer( layer ) )
  319. m_view->SetRequired( GetNetnameLayer( layer ), layer );
  320. else if( IsNetnameLayer( layer ) )
  321. m_view->SetLayerDisplayOnly( layer );
  322. }
  323. m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED );
  324. m_view->SetLayerDisplayOnly( LAYER_ANCHOR );
  325. // Some more required layers settings
  326. m_view->SetRequired( LAYER_VIAS_HOLES, LAYER_VIA_THROUGH );
  327. m_view->SetRequired( LAYER_VIAS_NETNAMES, LAYER_VIA_THROUGH );
  328. m_view->SetRequired( LAYER_PADS_HOLES, LAYER_PADS );
  329. m_view->SetRequired( LAYER_NON_PLATED, LAYER_PADS );
  330. m_view->SetRequired( LAYER_PADS_NETNAMES, LAYER_PADS );
  331. // Front modules
  332. m_view->SetRequired( LAYER_PAD_FR, LAYER_MOD_FR );
  333. m_view->SetRequired( LAYER_MOD_TEXT_FR, LAYER_MOD_FR );
  334. m_view->SetRequired( LAYER_PAD_FR_NETNAMES, LAYER_PAD_FR );
  335. m_view->SetRequired( F_Adhes, LAYER_PAD_FR );
  336. m_view->SetRequired( F_Paste, LAYER_PAD_FR );
  337. m_view->SetRequired( F_Mask, LAYER_PAD_FR );
  338. m_view->SetRequired( F_CrtYd, LAYER_MOD_FR );
  339. m_view->SetRequired( F_Fab, LAYER_MOD_FR );
  340. m_view->SetRequired( F_SilkS, LAYER_MOD_FR );
  341. // Back modules
  342. m_view->SetRequired( LAYER_PAD_BK, LAYER_MOD_BK );
  343. m_view->SetRequired( LAYER_MOD_TEXT_BK, LAYER_MOD_BK );
  344. m_view->SetRequired( LAYER_PAD_BK_NETNAMES, LAYER_PAD_BK );
  345. m_view->SetRequired( B_Adhes, LAYER_PAD_BK );
  346. m_view->SetRequired( B_Paste, LAYER_PAD_BK );
  347. m_view->SetRequired( B_Mask, LAYER_PAD_BK );
  348. m_view->SetRequired( B_CrtYd, LAYER_MOD_BK );
  349. m_view->SetRequired( B_Fab, LAYER_MOD_BK );
  350. m_view->SetRequired( B_SilkS, LAYER_MOD_BK );
  351. m_view->SetLayerTarget( LAYER_GP_OVERLAY , KIGFX::TARGET_OVERLAY );
  352. m_view->SetLayerDisplayOnly( LAYER_GP_OVERLAY ) ;
  353. m_view->SetLayerTarget( LAYER_RATSNEST, KIGFX::TARGET_OVERLAY );
  354. m_view->SetLayerDisplayOnly( LAYER_RATSNEST );
  355. m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
  356. m_view->SetLayerDisplayOnly( LAYER_GRID );
  357. m_view->SetLayerDisplayOnly( LAYER_DRC );
  358. }