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.

383 lines
14 KiB

  1. /*******************************************************/
  2. /* Dialog frame to choose gerber layers and pcb layers */
  3. /*******************************************************/
  4. /* select_layers_to_pcb.cpp */
  5. #include "fctsys.h"
  6. #include "common.h"
  7. #include "gerbview.h"
  8. #include "protos.h"
  9. #include "wx/statline.h"
  10. /* Variables locales */
  11. #define LAYER_UNSELECTED NB_LAYERS
  12. static int ButtonTable[32]; // Indexes buttons to Gerber layers
  13. static int LayerLookUpTable[32]; // Indexes Gerber layers to PCB file layers
  14. wxStaticText* layer_list[32]; // Indexes text strings to buttons
  15. enum swap_layer_id {
  16. ID_WINEDA_SWAPLAYERFRAME = 1800,
  17. ID_BUTTON_0,
  18. ID_TEXT_0 = ID_BUTTON_0 + 32
  19. };
  20. /***********************************************/
  21. /* classe pour la frame de selection de layers */
  22. /***********************************************/
  23. class WinEDA_SwapLayerFrame: public wxDialog
  24. {
  25. private:
  26. WinEDA_GerberFrame* m_Parent;
  27. wxBoxSizer* OuterBoxSizer;
  28. wxBoxSizer* MainBoxSizer;
  29. wxFlexGridSizer* FlexColumnBoxSizer;
  30. wxStaticText* label;
  31. wxButton* Button;
  32. wxStaticText* text;
  33. wxStaticLine* Line;
  34. wxStdDialogButtonSizer* StdDialogButtonSizer;
  35. public:
  36. // Constructor and destructor
  37. WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent);
  38. ~WinEDA_SwapLayerFrame() {};
  39. private:
  40. void Sel_Layer(wxCommandEvent& event);
  41. void OnOkClick(wxCommandEvent& event);
  42. void OnCancelClick(wxCommandEvent& event);
  43. DECLARE_EVENT_TABLE()
  44. };
  45. /* Table des evenements pour WinEDA_SwapLayerFrame */
  46. BEGIN_EVENT_TABLE(WinEDA_SwapLayerFrame, wxDialog)
  47. EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + 31,
  48. wxEVT_COMMAND_BUTTON_CLICKED,
  49. WinEDA_SwapLayerFrame::Sel_Layer )
  50. EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
  51. EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
  52. END_EVENT_TABLE()
  53. /*************************************************************/
  54. int * InstallDialogLayerPairChoice(WinEDA_GerberFrame * parent)
  55. /*************************************************************/
  56. /* Install a dialog frame to choose the equivalence
  57. * between gerber layers and pcbnew layers
  58. * return the "lookup table" if ok, or NULL
  59. */
  60. {
  61. WinEDA_SwapLayerFrame * frame = new WinEDA_SwapLayerFrame(parent);
  62. int ii = frame->ShowModal();
  63. frame->Destroy();
  64. if( ii >= 0 )
  65. return LayerLookUpTable;
  66. else
  67. return NULL;
  68. }
  69. /*************************************************************************/
  70. WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame(WinEDA_GerberFrame *parent) :
  71. wxDialog( parent, -1, _("Layer selection:"), wxPoint(-1, -1),
  72. wxDefaultSize, wxDEFAULT_DIALOG_STYLE|MAYBE_RESIZE_BORDER )
  73. /*************************************************************************/
  74. {
  75. OuterBoxSizer = NULL;
  76. MainBoxSizer = NULL;
  77. FlexColumnBoxSizer = NULL;
  78. label = NULL;
  79. Button = NULL;
  80. text = NULL;
  81. Line = NULL;
  82. StdDialogButtonSizer = NULL;
  83. m_Parent = parent;
  84. SetFont( *g_DialogFont );
  85. int item_ID, ii, nb_items;
  86. wxString msg;
  87. wxSize goodSize;
  88. // Experimentation has shown that buttons in the Windows version can be 20 pixels
  89. // wide and 20 pixels high, but that they need to be 26 pixels wide and 26 pixels
  90. // high in the Linux version. (And although the dimensions of those buttons could
  91. // be set to 26 pixels wide and 26 pixels high in both of those versions, that would
  92. // result in a dialog box which would be excessively high in the Windows version.)
  93. #ifdef __WINDOWS__
  94. int w = 20;
  95. int h = 20;
  96. #else
  97. int w = 26;
  98. int h = 26;
  99. #endif
  100. // As currently implemented, the dimensions of the buttons in the Mac version are
  101. // also 26 pixels wide and 26 pixels high. If appropriate, the above code should be
  102. // modified as required in the event that those buttons should be some other size
  103. // in that version.
  104. // Compute a reasonable number of copper layers
  105. g_DesignSettings.m_CopperLayerCount = 0;
  106. for( ii = 0; ii < 32; ii++ )
  107. {
  108. if( g_GERBER_Descr_List[ii] != NULL )
  109. g_DesignSettings.m_CopperLayerCount++;
  110. // Specify the default value for each member of these arrays.
  111. ButtonTable[ii] = -1;
  112. LayerLookUpTable[ii] = LAYER_UNSELECTED; // Value associated with deselected Gerber layer
  113. }
  114. int pcb_layer_number = 0;
  115. for( nb_items = 0, ii = 0; ii < 32; ii++ )
  116. {
  117. if( g_GERBER_Descr_List[ii] == NULL )
  118. continue;
  119. if( (pcb_layer_number == g_DesignSettings.m_CopperLayerCount - 1)
  120. && (g_DesignSettings.m_CopperLayerCount > 1) )
  121. pcb_layer_number = CMP_N;
  122. ButtonTable[nb_items] = ii;
  123. LayerLookUpTable[ii] = pcb_layer_number;
  124. nb_items++;
  125. pcb_layer_number++;
  126. }
  127. OuterBoxSizer = new wxBoxSizer(wxVERTICAL);
  128. SetSizer(OuterBoxSizer);
  129. MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
  130. OuterBoxSizer->Add(MainBoxSizer, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
  131. for( ii = 0; ii < nb_items; ii++ )
  132. {
  133. // If more than 16 Gerber layers are used, provide a vertical line to
  134. // separate the two FlexGrid sizers
  135. if( (nb_items > 16) && (ii == 16) )
  136. {
  137. Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
  138. MainBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT, 5);
  139. }
  140. // Provide a separate FlexGrid sizer for every sixteen sets of controls
  141. if( ii % 16 == 0 )
  142. {
  143. // Each Gerber layer has an associated static text string (to identify that layer),
  144. // a button (for invoking a child dialog box to change which pcbnew layer that the
  145. // Gerber layer is mapped to), and a second static text string (to depict which
  146. // pcbnew layer that the Gerber layer has been mapped to). Each of those items are
  147. // placed into the left hand column, middle column, and right hand column
  148. // (respectively) of the Flexgrid sizer, and the color of the second text string
  149. // is set to fushia or blue (to respectively indicate whether the Gerber layer has
  150. // been mapped to a pcbnew layer or is not being exported at all).
  151. // (Experimentation has shown that if a text control is used to depict which
  152. // pcbnew layer that each Gerber layer is mapped to (instead of a static text
  153. // string), then those controls do not behave in a fully satisfactory manner in
  154. // the Linux version. Even when the read-only attribute is specified for all of
  155. // those controls, they can still be selected when the arrow keys or Tab key is
  156. // used to step through all of the controls within the dialog box, and
  157. // directives to set the foreground color of the text of each such control to
  158. // blue (to indicate that the text is of a read-only nature) are disregarded.)
  159. // Specify a FlexGrid sizer with an appropriate number of rows and three columns.
  160. // If nb_items < 16, then the number of rows is nb_items; otherwise, the number of
  161. // rows is 16 (with two separate columns of controls being used if nb_items > 16).
  162. if( nb_items < 16 )
  163. FlexColumnBoxSizer = new wxFlexGridSizer(nb_items, 3, 0, 0);
  164. else
  165. FlexColumnBoxSizer = new wxFlexGridSizer(16, 3, 0, 0);
  166. // Specify that all of the rows can be expanded.
  167. for( int jj = 0; jj < MIN(nb_items, 16); jj++ )
  168. {
  169. FlexColumnBoxSizer->AddGrowableRow(jj);
  170. }
  171. // Specify that (just) the right-hand column can be expanded.
  172. FlexColumnBoxSizer->AddGrowableCol(2);
  173. MainBoxSizer->Add(FlexColumnBoxSizer, 1, wxGROW|wxTOP, 5);
  174. }
  175. // Provide a text string to identify the Gerber layer
  176. msg = _("Gerber layer ");
  177. msg << ButtonTable[ii] + 1;
  178. label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
  179. FlexColumnBoxSizer->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
  180. // Provide a button for this layer (which will invoke a child dialog box)
  181. item_ID = ID_BUTTON_0 + ii;
  182. Button = new wxButton( this, item_ID, wxT("..."), wxDefaultPosition, wxSize(w, h), 0 );
  183. FlexColumnBoxSizer->Add(Button, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxBOTTOM, 5);
  184. // Provide another text string to specify which pcbnew layer that this
  185. // Gerber layer is initially mapped to, and set the initial text to
  186. // specify the appropriate pcbnew layer, and set the foreground color
  187. // of the text to fushia (to indicate that the layer is being exported).
  188. item_ID = ID_TEXT_0 + ii;
  189. // When the first of these text strings is being added, determine what size is necessary to
  190. // to be able to display any possible string without it being truncated. Then specify that
  191. // size as the minimum size for all of these text strings. (If this minimum size is not
  192. // determined in this fashion, then it is possible for the display of one or more of these
  193. // strings to be truncated after different pcbnew layers are selected.)
  194. if( ii == 0 )
  195. {
  196. msg = _( "Do not export" );
  197. text = new wxStaticText( this, item_ID, msg, wxDefaultPosition, wxDefaultSize, 0 );
  198. goodSize = text->GetSize();
  199. for( int jj = 0; jj < NB_LAYERS; jj++ )
  200. {
  201. text->SetLabel( ReturnPcbLayerName( jj ) );
  202. if( goodSize.x < text->GetSize().x )
  203. goodSize.x = text->GetSize().x;
  204. }
  205. msg = ReturnPcbLayerName(LayerLookUpTable[ButtonTable[ii]]);
  206. text->SetLabel( msg );
  207. }
  208. else
  209. {
  210. msg = ReturnPcbLayerName(LayerLookUpTable[ButtonTable[ii]]);
  211. text = new wxStaticText( this, item_ID, msg, wxDefaultPosition, wxDefaultSize, 0 );
  212. }
  213. text->SetMinSize( goodSize );
  214. text->SetForegroundColour( wxColour(255, 0, 128) );
  215. FlexColumnBoxSizer->Add(text, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
  216. layer_list[ii] = text;
  217. }
  218. // If required, provide spacers to occupy otherwise blank cells within the
  219. // second FlexGrid sizer. (As it incorporates three columns, three spacers
  220. // are thus required for each otherwise unused row.)
  221. if( 16 < nb_items && nb_items < 32 )
  222. {
  223. for( ii = 3 * nb_items; ii < 96; ii++ )
  224. {
  225. FlexColumnBoxSizer->Add(5, h, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);
  226. }
  227. }
  228. // Provide a line to separate the controls which have been provided so far
  229. // from the OK and Cancel buttons (which will be provided after this line)
  230. Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
  231. OuterBoxSizer->Add(Line, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
  232. // Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
  233. // using that type of sizer results in those buttons being automatically
  234. // located in positions appropriate for each (OS) version of KiCad.
  235. StdDialogButtonSizer = new wxStdDialogButtonSizer;
  236. OuterBoxSizer->Add(StdDialogButtonSizer, 0, wxGROW|wxALL, 10);
  237. Button = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
  238. Button->SetForegroundColour( *wxRED );
  239. StdDialogButtonSizer->AddButton(Button);
  240. Button = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
  241. Button->SetForegroundColour( *wxBLUE );
  242. StdDialogButtonSizer->AddButton(Button);
  243. StdDialogButtonSizer->Realize();
  244. // Resize the dialog
  245. if( GetSizer() )
  246. {
  247. GetSizer()->SetSizeHints(this);
  248. }
  249. }
  250. /***************************************************************/
  251. void WinEDA_SwapLayerFrame::Sel_Layer(wxCommandEvent& event)
  252. /***************************************************************/
  253. {
  254. int ii, jj;
  255. ii = event.GetId();
  256. if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + 32 )
  257. return;
  258. ii = event.GetId() - ID_BUTTON_0;
  259. jj = LayerLookUpTable[ButtonTable[ii]];
  260. if( (jj < 0) || (jj > LAYER_UNSELECTED) )
  261. jj = 0; // (Defaults to "Copper" layer.)
  262. jj = m_Parent->SelectLayer(jj, -1, -1, true);
  263. if( (jj < 0) || (jj > LAYER_UNSELECTED) )
  264. return;
  265. if( jj != LayerLookUpTable[ButtonTable[ii]] )
  266. {
  267. LayerLookUpTable[ButtonTable[ii]] = jj;
  268. if( jj == LAYER_UNSELECTED )
  269. {
  270. layer_list[ii]->SetLabel( _( "Do not export" ) );
  271. // Change the text color to blue (to highlight
  272. // that this layer is *not* being exported)
  273. layer_list[ii]->SetForegroundColour( *wxBLUE );
  274. }
  275. else
  276. {
  277. layer_list[ii]->SetLabel( ReturnPcbLayerName( jj ) );
  278. // Change the text color to fushia (to highlight
  279. // that this layer *is* being exported)
  280. layer_list[ii]->SetForegroundColour( wxColour(255, 0, 128) );
  281. }
  282. }
  283. }
  284. /*********************************************************/
  285. void WinEDA_SwapLayerFrame::OnCancelClick(wxCommandEvent& event)
  286. /*********************************************************/
  287. {
  288. EndModal( -1 );
  289. }
  290. /*********************************************************/
  291. void WinEDA_SwapLayerFrame::OnOkClick(wxCommandEvent& event)
  292. /*********************************************************/
  293. {
  294. int ii;
  295. bool AsCmpLayer = false;
  296. /* Compute the number of copper layers
  297. * this is the max layer number + 1 (if some internal layers exist)
  298. */
  299. g_DesignSettings.m_CopperLayerCount = 1;
  300. for( ii = 0; ii < 32; ii++ )
  301. {
  302. if( LayerLookUpTable[ii] == CMP_N )
  303. AsCmpLayer = true;
  304. else
  305. {
  306. if( LayerLookUpTable[ii] >= LAST_COPPER_LAYER )
  307. continue; // not a copper layer
  308. if( LayerLookUpTable[ii] >= g_DesignSettings.m_CopperLayerCount )
  309. g_DesignSettings.m_CopperLayerCount++;
  310. }
  311. }
  312. if( AsCmpLayer )
  313. g_DesignSettings.m_CopperLayerCount++;
  314. if( g_DesignSettings.m_CopperLayerCount > NB_COPPER_LAYERS ) // should not occur.
  315. g_DesignSettings.m_CopperLayerCount = NB_COPPER_LAYERS;
  316. EndModal( 1 );
  317. }