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.

299 lines
8.3 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. /**
  24. * @file dialog_set_grid.cpp
  25. * @brief Manage user grid.
  26. */
  27. #include <dialog_set_grid_base.h>
  28. #include <base_units.h>
  29. #include <convert_to_biu.h>
  30. #include <common.h>
  31. #include <pcb_base_frame.h>
  32. #include <class_drawpanel.h>
  33. #include <class_draw_panel_gal.h>
  34. #include <gal/graphics_abstraction_layer.h>
  35. #include <tools/pcb_actions.h>
  36. #include <tool/tool_manager.h>
  37. #include <limits.h>
  38. // Max values for grid size
  39. static const double MAX_GRID_SIZE = 1000.0 * IU_PER_MM;
  40. static const double MIN_GRID_SIZE = 0.001 * IU_PER_MM;
  41. // Min/Max value for grid offset
  42. static const double MAX_GRID_OFFSET = INT_MAX / 2.0;
  43. class DIALOG_SET_GRID : public DIALOG_SET_GRID_BASE
  44. {
  45. PCB_BASE_FRAME* m_parent;
  46. wxArrayString m_fast_grid_opts;
  47. public:
  48. /// This has no dependencies on calling wxFrame derivative, such as PCB_BASE_FRAME.
  49. DIALOG_SET_GRID( PCB_BASE_FRAME* aParent, const wxArrayString& aGridChoices );
  50. bool TransferDataFromWindow() override;
  51. bool TransferDataToWindow() override;
  52. private:
  53. void OnResetGridOrgClick( wxCommandEvent& event ) override;
  54. void OnInitDlg( wxInitDialogEvent& event ) override
  55. {
  56. // Call the default wxDialog handler of a wxInitDialogEvent
  57. TransferDataToWindow();
  58. // Now all widgets have the size fixed, call FinishDialogSettings
  59. FinishDialogSettings();
  60. }
  61. void setGridUnits( EDA_UNITS_T units );
  62. EDA_UNITS_T getGridUnits();
  63. void setGridSize( const wxRealPoint& grid );
  64. bool getGridSize( wxRealPoint& aGrisSize );
  65. void setGridOrigin( const wxPoint& grid );
  66. bool getGridOrigin( wxPoint& aGridOrigin );
  67. void setGridForFastSwitching( const wxArrayString& aGrids, int aGrid1, int aGrid2 );
  68. void getGridForFastSwitching( int& aGrid1, int& aGrid2 );
  69. };
  70. DIALOG_SET_GRID::DIALOG_SET_GRID( PCB_BASE_FRAME* aParent, const wxArrayString& aGridChoices ):
  71. DIALOG_SET_GRID_BASE( aParent ),
  72. m_parent( aParent ),
  73. m_fast_grid_opts( aGridChoices )
  74. {
  75. m_sdbSizerOK->SetDefault(); // set OK button as default response to 'Enter' key
  76. m_TextPosXUnits->SetLabel( GetUnitsLabel( m_parent->m_UserGridUnit ) );
  77. m_TextPosYUnits->SetLabel( GetUnitsLabel( m_parent->m_UserGridUnit ) );
  78. }
  79. bool DIALOG_SET_GRID::TransferDataFromWindow()
  80. {
  81. // Validate new settings
  82. wxRealPoint gridSize;
  83. if( !getGridSize( gridSize ) )
  84. {
  85. wxMessageBox( wxString::Format( _( "Incorrect grid size "
  86. "(size must be >= %.3f mm and <= %.3f mm)" ),
  87. MIN_GRID_SIZE/IU_PER_MM, MAX_GRID_SIZE/IU_PER_MM ) );
  88. return false;
  89. }
  90. wxPoint gridOrigin;
  91. if( !getGridOrigin( gridOrigin ) )
  92. {
  93. wxMessageBox( wxString::Format( _( "Incorrect grid origin "
  94. "(coordinates must be >= %.3f mm and <= %.3f mm)" ),
  95. -MAX_GRID_OFFSET/IU_PER_MM, MAX_GRID_OFFSET/IU_PER_MM ) );
  96. return false;
  97. }
  98. int fastGrid1, fastGrid2;
  99. getGridForFastSwitching( fastGrid1, fastGrid2 );
  100. EDA_UNITS_T units = getGridUnits();
  101. // Apply the new settings
  102. // Because grid origin is saved in board, show as modified
  103. m_parent->OnModify();
  104. m_parent->SetGridOrigin( gridOrigin );
  105. m_parent->m_UserGridUnit = units;
  106. m_parent->m_UserGridSize = gridSize;
  107. m_parent->m_FastGrid1 = fastGrid1;
  108. m_parent->m_FastGrid2 = fastGrid2;
  109. // User grid
  110. BASE_SCREEN* screen = m_parent->GetScreen();
  111. screen->AddGrid( gridSize, units, ID_POPUP_GRID_USER );
  112. // If the user grid is the current option, recall SetGrid()
  113. // to force new values put in list as current grid value
  114. if( screen->GetGridCmdId() == ID_POPUP_GRID_USER )
  115. screen->SetGrid( ID_POPUP_GRID_USER );
  116. // Notify GAL
  117. TOOL_MANAGER* mgr = m_parent->GetToolManager();
  118. if( mgr && m_parent->IsGalCanvasActive() )
  119. {
  120. mgr->RunAction( "common.Control.gridPreset", true,
  121. screen->GetGridCmdId() - ID_POPUP_GRID_LEVEL_1000 );
  122. TOOL_EVENT gridOriginUpdate = ACTIONS::gridSetOrigin.MakeEvent();
  123. gridOriginUpdate.SetParameter( new VECTOR2D( gridOrigin ) );
  124. mgr->ProcessEvent( gridOriginUpdate );
  125. }
  126. return wxDialog::TransferDataFromWindow();
  127. }
  128. bool DIALOG_SET_GRID::TransferDataToWindow()
  129. {
  130. setGridUnits( m_parent->m_UserGridUnit );
  131. setGridSize( m_parent->m_UserGridSize );
  132. setGridOrigin( m_parent->GetGridOrigin() );
  133. setGridForFastSwitching( m_fast_grid_opts, m_parent->m_FastGrid1, m_parent->m_FastGrid2 );
  134. return wxDialog::TransferDataToWindow();
  135. }
  136. void DIALOG_SET_GRID::setGridUnits( EDA_UNITS_T aUnits )
  137. {
  138. m_UnitGrid->SetSelection( aUnits != INCHES );
  139. }
  140. EDA_UNITS_T DIALOG_SET_GRID::getGridUnits()
  141. {
  142. return m_UnitGrid->GetSelection() == 0 ? INCHES : MILLIMETRES;
  143. }
  144. void DIALOG_SET_GRID::setGridSize( const wxRealPoint& grid )
  145. {
  146. wxString msg;
  147. msg.Printf( wxT( "%.10g" ), grid.x );
  148. m_OptGridSizeX->SetValue( msg );
  149. msg.Printf( wxT( "%.10g" ), grid.y );
  150. m_OptGridSizeY->SetValue( msg );
  151. }
  152. bool DIALOG_SET_GRID::getGridSize( wxRealPoint& aGrisSize )
  153. {
  154. wxRealPoint grid;
  155. wxString val = m_OptGridSizeX->GetValue();
  156. double grid_unit_to_iu = ( getGridUnits() == INCHES ? IU_PER_MILS * 1000 : IU_PER_MM );
  157. double tmp;
  158. if( !val.ToDouble( &tmp ) ||
  159. tmp * grid_unit_to_iu < MIN_GRID_SIZE || tmp * grid_unit_to_iu > MAX_GRID_SIZE )
  160. {
  161. return false;
  162. }
  163. else
  164. aGrisSize.x = tmp;
  165. val = m_OptGridSizeY->GetValue();
  166. if( !val.ToDouble( &tmp ) ||
  167. tmp*grid_unit_to_iu < MIN_GRID_SIZE || tmp*grid_unit_to_iu > MAX_GRID_SIZE )
  168. {
  169. return false;
  170. }
  171. else
  172. aGrisSize.y = tmp;
  173. return true;
  174. }
  175. bool DIALOG_SET_GRID::getGridOrigin( wxPoint& aGridOrigin )
  176. {
  177. double x, y;
  178. const wxString& x_str = m_GridOriginXCtrl->GetValue();
  179. if( !x_str.ToDouble( &x ) )
  180. return false;
  181. x = DoubleValueFromString( g_UserUnit, x_str );
  182. // Some error checking here is a good thing.
  183. if( x < -MAX_GRID_OFFSET || x > MAX_GRID_OFFSET )
  184. return false;
  185. const wxString& y_str = m_GridOriginYCtrl->GetValue();
  186. if( !y_str.ToDouble( &y ) )
  187. return false;
  188. y = DoubleValueFromString( g_UserUnit, y_str );
  189. if( y < -MAX_GRID_OFFSET || y > MAX_GRID_OFFSET )
  190. return false;
  191. aGridOrigin.x = KiROUND( x );
  192. aGridOrigin.y = KiROUND( y );
  193. return true;
  194. }
  195. void DIALOG_SET_GRID::setGridOrigin( const wxPoint& grid )
  196. {
  197. PutValueInLocalUnits( *m_GridOriginXCtrl, grid.x );
  198. PutValueInLocalUnits( *m_GridOriginYCtrl, grid.y );
  199. }
  200. void DIALOG_SET_GRID::setGridForFastSwitching( const wxArrayString& aGrids, int aGrid1, int aGrid2 )
  201. {
  202. m_comboBoxGrid1->Append( aGrids );
  203. m_comboBoxGrid2->Append( aGrids );
  204. m_comboBoxGrid1->SetSelection( aGrid1 );
  205. m_comboBoxGrid2->SetSelection( aGrid2 );
  206. }
  207. void DIALOG_SET_GRID::getGridForFastSwitching( int& aGrid1, int& aGrid2 )
  208. {
  209. aGrid1 = m_comboBoxGrid1->GetSelection();
  210. aGrid2 = m_comboBoxGrid2->GetSelection();
  211. }
  212. void DIALOG_SET_GRID::OnResetGridOrgClick( wxCommandEvent& event )
  213. {
  214. setGridOrigin( wxPoint( 0, 0 ) );
  215. }
  216. bool PCB_BASE_FRAME::InvokeDialogGrid()
  217. {
  218. DIALOG_SET_GRID dlg( this, m_gridSelectBox->GetStrings() );
  219. return dlg.ShowModal();
  220. }