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.

275 lines
9.1 KiB

  1. /*
  2. * This program source code file is part of KICAD, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
  5. * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /*********************************************************/
  26. /* class_gerbview_layer_widget.cpp - gerbview layers manager. */
  27. /*********************************************************/
  28. #include "fctsys.h"
  29. #include "common.h"
  30. #include "class_drawpanel.h"
  31. #include "pcbstruct.h"
  32. #include "gerbview.h"
  33. #include "class_GERBER.h"
  34. #include "layer_widget.h"
  35. #include "class_gerbview_layer_widget.h"
  36. /*
  37. * Class GERBER_LAYER_WIDGET
  38. * is here to implement the abtract functions of LAYER_WIDGET so they
  39. * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
  40. * menu which is specific to PCBNEW's needs.
  41. */
  42. GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize ) :
  43. LAYER_WIDGET( aParent, aFocusOwner, aPointSize ),
  44. myframe( aParent )
  45. {
  46. BOARD* board = myframe->GetBoard();
  47. // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
  48. // is changed before appending to the LAYER_WIDGET. This is an automatic variable
  49. // not a static variable, change the color & state after copying from code to renderRows
  50. // on the stack.
  51. LAYER_WIDGET::ROW renderRows[2] = {
  52. #define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
  53. // text id color tooltip checked
  54. RR( _( "Grid" ), GERBER_GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ),
  55. RR( _( "DCodes" ), DCODES_VISIBLE, WHITE, _( "Show DCodes identification" ) ),
  56. };
  57. for( unsigned row=0; row<DIM(renderRows); ++row )
  58. {
  59. if( renderRows[row].color != -1 ) // does this row show a color?
  60. {
  61. // this window frame must have an established BOARD, i.e. after SetBoard()
  62. renderRows[row].color = board->GetVisibleElementColor( renderRows[row].id );
  63. }
  64. renderRows[row].state = board->IsElementVisible( renderRows[row].id );
  65. }
  66. AppendRenderRows( renderRows, DIM(renderRows) );
  67. // Update default tabs labels for gerbview
  68. SetLayersManagerTabsText( );
  69. //-----<Popup menu>-------------------------------------------------
  70. // handle the popup menu over the layer window.
  71. m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
  72. wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
  73. // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
  74. // and not m_LayerScrolledWindow->Connect()
  75. Connect( ID_SHOW_ALL_COPPERS, ID_SHOW_NO_COPPERS, wxEVT_COMMAND_MENU_SELECTED,
  76. wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );
  77. // install the right click handler into each control at end of ReFill()
  78. // using installRightLayerClickHandler
  79. }
  80. /**
  81. * Function SetLayersManagerTabsText
  82. * Update the layer manager tabs labels
  83. * Useful when changing Language or to set labels to a non default value
  84. */
  85. void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( )
  86. {
  87. m_notebook->SetPageText(0, _("Layer") );
  88. m_notebook->SetPageText(1, _("Render") );
  89. }
  90. void GERBER_LAYER_WIDGET::installRightLayerClickHandler()
  91. {
  92. int rowCount = GetLayerRowCount();
  93. for( int row=0; row<rowCount; ++row )
  94. {
  95. for( int col=0; col<LYR_COLUMN_COUNT; ++col )
  96. {
  97. wxWindow* w = getLayerComp( row, col );
  98. w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
  99. GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
  100. }
  101. }
  102. }
  103. void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
  104. {
  105. wxMenu menu;
  106. // menu text is capitalized:
  107. // http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
  108. menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS,
  109. _("Show All Layers") ) );
  110. menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS,
  111. _( "Hide All Layers" ) ) );
  112. PopupMenu( &menu );
  113. passOnFocus();
  114. }
  115. void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
  116. {
  117. int rowCount;
  118. int menuId = event.GetId();
  119. bool visible = (menuId == ID_SHOW_ALL_COPPERS) ? true : false;;
  120. int visibleLayers = 0;
  121. switch( menuId )
  122. {
  123. case ID_SHOW_ALL_COPPERS:
  124. case ID_SHOW_NO_COPPERS:
  125. rowCount = GetLayerRowCount();
  126. for( int row=0; row < rowCount; ++row )
  127. {
  128. wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 );
  129. cb->SetValue( visible );
  130. if( visible )
  131. visibleLayers |= (1 << row);
  132. else
  133. visibleLayers &= ~(1 << row);
  134. }
  135. myframe->GetBoard()->SetVisibleLayers( visibleLayers );
  136. myframe->DrawPanel->Refresh();
  137. break;
  138. }
  139. }
  140. void GERBER_LAYER_WIDGET::ReFill()
  141. {
  142. BOARD* brd = myframe->GetBoard();
  143. int layer;
  144. ClearLayerRows();
  145. for( layer = 0; layer < LAYER_COUNT; layer++ )
  146. {
  147. wxString msg;
  148. msg.Printf( _("Layer %d"), layer+1 );
  149. AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
  150. brd->GetLayerColor( layer ), wxEmptyString, true ) );
  151. }
  152. installRightLayerClickHandler();
  153. }
  154. //-----<LAYER_WIDGET callbacks>-------------------------------------------
  155. void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, int aColor )
  156. {
  157. myframe->GetBoard()->SetLayerColor( aLayer, aColor );
  158. myframe->m_SelLayerBox->ResyncBitmapOnly();
  159. myframe->DrawPanel->Refresh();
  160. }
  161. bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer )
  162. {
  163. // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
  164. // false from this function.
  165. int layer = myframe->getActiveLayer( );
  166. myframe->setActiveLayer( aLayer, false );
  167. myframe->syncLayerBox();
  168. if( layer != myframe->getActiveLayer( ) )
  169. myframe->DrawPanel->Refresh();
  170. return true;
  171. }
  172. void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
  173. {
  174. BOARD* brd = myframe->GetBoard();
  175. int visibleLayers = brd->GetVisibleLayers();
  176. if( isVisible )
  177. visibleLayers |= (1 << aLayer);
  178. else
  179. visibleLayers &= ~(1 << aLayer);
  180. brd->SetVisibleLayers( visibleLayers );
  181. if( isFinal )
  182. myframe->DrawPanel->Refresh();
  183. }
  184. void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, int aColor )
  185. {
  186. myframe->GetBoard()->SetVisibleElementColor( aId, aColor );
  187. myframe->DrawPanel->Refresh();
  188. }
  189. void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
  190. {
  191. BOARD* brd = myframe->GetBoard();
  192. brd->SetElementVisibility( aId, isEnabled );
  193. myframe->DrawPanel->Refresh();
  194. }
  195. //-----</LAYER_WIDGET callbacks>------------------------------------------
  196. /*
  197. * Virtual Function useAlternateBitmap
  198. * return true if bitmaps shown in Render layer list
  199. * must be alternate bitmaps, or false to use "normal" bitmaps
  200. */
  201. bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
  202. {
  203. bool inUse = false;
  204. GERBER_IMAGE* gerber = g_GERBER_List[aRow];
  205. if( gerber != NULL && gerber->m_InUse )
  206. inUse = true;
  207. return inUse;
  208. }
  209. /**
  210. * Function UpdateLayerIcons
  211. * Update the layer manager icons (layers only)
  212. * Useful when loading a file or clearing a layer because they change
  213. */
  214. void GERBER_LAYER_WIDGET::UpdateLayerIcons()
  215. {
  216. int row_count = GetLayerRowCount();
  217. for( int row = 0; row < row_count ; row++ )
  218. {
  219. wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, 0 );
  220. if( bm == NULL)
  221. continue;
  222. if( row == m_CurrentRow )
  223. bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap : *m_RightArrowBitmap );
  224. else
  225. bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
  226. }
  227. }