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.

441 lines
14 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019 Jean-Pierre Charras jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * 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. /*
  25. * Edit properties of Lines, Circles, Arcs and Polygons for PCBNew and Footprint Editor
  26. */
  27. #include <pcb_base_edit_frame.h>
  28. #include <wx/valnum.h>
  29. #include <board_commit.h>
  30. #include <pcb_layer_box_selector.h>
  31. #include <dialogs/html_messagebox.h>
  32. #include <pcb_shape.h>
  33. #include <fp_shape.h>
  34. #include <confirm.h>
  35. #include <widgets/unit_binder.h>
  36. #include <dialog_graphic_item_properties_base.h>
  37. class DIALOG_GRAPHIC_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
  38. {
  39. private:
  40. PCB_BASE_EDIT_FRAME* m_parent;
  41. PCB_SHAPE* m_item;
  42. FP_SHAPE* m_fp_item;
  43. UNIT_BINDER m_startX, m_startY;
  44. UNIT_BINDER m_endX, m_endY;
  45. UNIT_BINDER m_angle;
  46. UNIT_BINDER m_thickness;
  47. UNIT_BINDER m_bezierCtrl1X, m_bezierCtrl1Y;
  48. UNIT_BINDER m_bezierCtrl2X, m_bezierCtrl2Y;
  49. bool m_flipStartEnd;
  50. wxFloatingPointValidator<double> m_AngleValidator;
  51. double m_AngleValue;
  52. public:
  53. DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem );
  54. ~DIALOG_GRAPHIC_ITEM_PROPERTIES() {};
  55. private:
  56. bool TransferDataToWindow() override;
  57. bool TransferDataFromWindow() override;
  58. void OnInitDlg( wxInitDialogEvent& event ) override
  59. {
  60. // Call the default wxDialog handler of a wxInitDialogEvent
  61. TransferDataToWindow();
  62. // Now all widgets have the size fixed, call FinishDialogSettings
  63. finishDialogSettings();
  64. }
  65. bool Validate() override;
  66. void onLayer( wxCommandEvent& event ) override;
  67. };
  68. DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
  69. BOARD_ITEM* aItem ):
  70. DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent ),
  71. m_startX( aParent, m_startXLabel, m_startXCtrl, m_startXUnits ),
  72. m_startY( aParent, m_startYLabel, m_startYCtrl, m_startYUnits ),
  73. m_endX( aParent, m_endXLabel, m_endXCtrl, m_endXUnits ),
  74. m_endY( aParent, m_endYLabel, m_endYCtrl, m_endYUnits ),
  75. m_angle( aParent, m_angleLabel, m_angleCtrl, m_angleUnits ),
  76. m_thickness( aParent, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true ),
  77. m_bezierCtrl1X( aParent, m_BezierPointC1XLabel, m_BezierC1X_Ctrl, m_BezierPointC1XUnit ),
  78. m_bezierCtrl1Y( aParent, m_BezierPointC1YLabel, m_BezierC1Y_Ctrl, m_BezierPointC1YUnit ),
  79. m_bezierCtrl2X( aParent, m_BezierPointC2XLabel, m_BezierC2X_Ctrl, m_BezierPointC2XUnit ),
  80. m_bezierCtrl2Y( aParent, m_BezierPointC2YLabel, m_BezierC2Y_Ctrl, m_BezierPointC2YUnit ),
  81. m_flipStartEnd( false ),
  82. m_AngleValidator( 1, &m_AngleValue ),
  83. m_AngleValue( 0.0 )
  84. {
  85. m_parent = aParent;
  86. m_item = dynamic_cast<PCB_SHAPE*>( aItem );
  87. m_fp_item = dynamic_cast<FP_SHAPE*>( aItem );
  88. // Configure display origin transforms
  89. m_startX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  90. m_startY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  91. m_endX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  92. m_endY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  93. m_bezierCtrl1X.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  94. m_bezierCtrl1Y.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  95. m_bezierCtrl2X.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
  96. m_bezierCtrl2Y.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
  97. m_angle.SetUnits( EDA_UNITS::DEGREES );
  98. m_AngleValidator.SetRange( -360.0, 360.0 );
  99. m_angleCtrl->SetValidator( m_AngleValidator );
  100. m_AngleValidator.SetWindow( m_angleCtrl );
  101. // Configure the layers list selector
  102. if( m_fp_item )
  103. {
  104. LSET forbiddenLayers = LSET::ForbiddenFootprintLayers();
  105. // If someone went to the trouble of setting the layer in a text editor, then there's
  106. // very little sense in nagging them about it.
  107. forbiddenLayers.set( m_fp_item->GetLayer(), false );
  108. m_LayerSelectionCtrl->SetNotAllowedLayerSet( forbiddenLayers );
  109. }
  110. m_LayerSelectionCtrl->SetLayersHotkeys( false );
  111. m_LayerSelectionCtrl->SetBoardFrame( m_parent );
  112. m_LayerSelectionCtrl->Resync();
  113. SetInitialFocus( m_startXCtrl );
  114. m_StandardButtonsSizerOK->SetDefault();
  115. }
  116. void PCB_BASE_EDIT_FRAME::ShowGraphicItemPropertiesDialog( BOARD_ITEM* aItem )
  117. {
  118. wxCHECK_RET( aItem != NULL, wxT( "ShowGraphicItemPropertiesDialog() error: NULL item" ) );
  119. DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem );
  120. dlg.ShowModal();
  121. }
  122. bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow()
  123. {
  124. if( !m_item )
  125. return false;
  126. // Only an arc has a angle parameter. So do not show this parameter for other shapes
  127. if( m_item->GetShape() != S_ARC )
  128. m_angle.Show( false );
  129. // Only a Bezeier curve has control points. So do not show these parameters for other shapes
  130. if( m_item->GetShape() != S_CURVE )
  131. {
  132. m_bezierCtrlPt1Label->Show( false );
  133. m_bezierCtrl1X.Show( false );
  134. m_bezierCtrl1Y.Show( false );
  135. m_bezierCtrlPt2Label->Show( false );
  136. m_bezierCtrl2X.Show( false );
  137. m_bezierCtrl2Y.Show( false );
  138. }
  139. // Change texts according to the segment shape:
  140. switch( m_item->GetShape() )
  141. {
  142. case S_CIRCLE:
  143. SetTitle( _( "Circle Properties" ) );
  144. m_startPointLabel->SetLabel( _( "Center" ) );
  145. m_endPointLabel->SetLabel( _( "Radius" ) );
  146. m_endXLabel->Show( false );
  147. m_endX.SetCoordType( ORIGIN_TRANSFORMS::NOT_A_COORD );
  148. m_endY.Show( false );
  149. m_filledCtrl->Show( true );
  150. break;
  151. case S_ARC:
  152. SetTitle( _( "Arc Properties" ) );
  153. m_AngleValue = m_item->GetAngle() / 10.0;
  154. m_filledCtrl->Show( false );
  155. break;
  156. case S_POLYGON:
  157. {
  158. LSET graphicPolygonsLayers = LSET::AllLayersMask();
  159. graphicPolygonsLayers.reset( Edge_Cuts ).reset( F_CrtYd ).reset( B_CrtYd );
  160. SetTitle( _( "Polygon Properties" ) );
  161. m_sizerLeft->Show( false );
  162. m_filledCtrl->Show( true );
  163. m_filledCtrl->Enable( graphicPolygonsLayers.Contains( m_item->GetLayer() ) );
  164. // Prevent courtyard/edge cuts from being filled
  165. if( !graphicPolygonsLayers.Contains( m_item->GetLayer() ) )
  166. m_filledCtrl->SetValue( false );
  167. break;
  168. }
  169. case S_RECT:
  170. SetTitle( _( "Rectangle Properties" ) );
  171. m_filledCtrl->Show( true );
  172. break;
  173. case S_SEGMENT:
  174. if( m_item->GetStart().x == m_item->GetEnd().x )
  175. m_flipStartEnd = m_item->GetStart().y > m_item->GetEnd().y;
  176. else
  177. m_flipStartEnd = m_item->GetStart().x > m_item->GetEnd().x;
  178. SetTitle( _( "Line Segment Properties" ) );
  179. m_filledCtrl->Show( false );
  180. break;
  181. default:
  182. break;
  183. }
  184. if( m_item->GetShape() == S_ARC )
  185. {
  186. m_startX.SetValue( m_item->GetArcStart().x );
  187. m_startY.SetValue( m_item->GetArcStart().y );
  188. }
  189. else if( m_flipStartEnd )
  190. {
  191. m_startX.SetValue( m_item->GetEnd().x );
  192. m_startY.SetValue( m_item->GetEnd().y );
  193. }
  194. else
  195. {
  196. m_startX.SetValue( m_item->GetStart().x );
  197. m_startY.SetValue( m_item->GetStart().y );
  198. }
  199. if( m_item->GetShape() == S_CIRCLE )
  200. {
  201. m_endX.SetValue( m_item->GetRadius() );
  202. }
  203. else if( m_item->GetShape() == S_ARC )
  204. {
  205. m_endX.SetValue( m_item->GetArcEnd().x );
  206. m_endY.SetValue( m_item->GetArcEnd().y );
  207. }
  208. else if( m_flipStartEnd )
  209. {
  210. m_endX.SetValue( m_item->GetStart().x );
  211. m_endY.SetValue( m_item->GetStart().y );
  212. }
  213. else
  214. {
  215. m_endX.SetValue( m_item->GetEnd().x );
  216. m_endY.SetValue( m_item->GetEnd().y );
  217. }
  218. // For Bezier curve:
  219. m_bezierCtrl1X.SetValue( m_item->GetBezControl1().x );
  220. m_bezierCtrl1Y.SetValue( m_item->GetBezControl1().y );
  221. m_bezierCtrl2X.SetValue( m_item->GetBezControl2().x );
  222. m_bezierCtrl2Y.SetValue( m_item->GetBezControl2().y );
  223. m_filledCtrl->SetValue( m_item->IsFilled() );
  224. m_thickness.SetValue( m_item->GetWidth() );
  225. m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() );
  226. return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow();
  227. }
  228. bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
  229. {
  230. if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
  231. return false;
  232. if( !m_thickness.Validate( 0, Millimeter2iu( 1000.0 ) ) )
  233. return false;
  234. if( m_thickness.GetValue() == 0 && !m_filledCtrl->GetValue() )
  235. {
  236. DisplayError( this, _( "Line width may not be 0 for unfilled shapes." ) );
  237. m_thicknessCtrl->SetFocus();
  238. return false;
  239. }
  240. LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();
  241. BOARD_COMMIT commit( m_parent );
  242. commit.Modify( m_item );
  243. if( m_item->GetShape() == S_ARC )
  244. {
  245. m_item->SetArcStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
  246. }
  247. else if( m_flipStartEnd )
  248. {
  249. m_item->SetEndX( m_startX.GetValue() );
  250. m_item->SetEndY( m_startY.GetValue() );
  251. }
  252. else
  253. {
  254. m_item->SetStartX( m_startX.GetValue() );
  255. m_item->SetStartY( m_startY.GetValue() );
  256. }
  257. if( m_item->GetShape() == S_CIRCLE )
  258. {
  259. m_item->SetEnd( m_item->GetStart() + wxPoint( m_endX.GetValue(), 0 ) );
  260. }
  261. else if( m_item->GetShape() == S_ARC )
  262. {
  263. m_item->SetArcEnd( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
  264. }
  265. else if( m_flipStartEnd )
  266. {
  267. m_item->SetStartX( m_endX.GetValue() );
  268. m_item->SetStartY( m_endY.GetValue() );
  269. }
  270. else
  271. {
  272. m_item->SetEndX( m_endX.GetValue() );
  273. m_item->SetEndY( m_endY.GetValue() );
  274. }
  275. // For Bezier curve: Set the two control points
  276. if( m_item->GetShape() == S_CURVE )
  277. {
  278. m_item->SetBezControl1( wxPoint( m_bezierCtrl1X.GetValue(), m_bezierCtrl1Y.GetValue() ) );
  279. m_item->SetBezControl2( wxPoint( m_bezierCtrl2X.GetValue(), m_bezierCtrl2Y.GetValue() ) );
  280. }
  281. if( m_item->GetShape() == S_ARC )
  282. {
  283. m_item->SetCenter( GetArcCenter( m_item->GetArcStart(), m_item->GetArcEnd(), m_AngleValue ) );
  284. m_item->SetAngle( m_AngleValue * 10.0, false );
  285. }
  286. if( m_fp_item )
  287. {
  288. // We are editing a footprint; init the item coordinates relative to the footprint anchor.
  289. m_fp_item->SetStart0( m_fp_item->GetStart() );
  290. m_fp_item->SetEnd0( m_fp_item->GetEnd() );
  291. if( m_fp_item->GetShape() == S_CURVE )
  292. {
  293. m_fp_item->SetBezier0_C1( wxPoint( m_bezierCtrl1X.GetValue(), m_bezierCtrl1Y.GetValue() ) );
  294. m_fp_item->SetBezier0_C2( wxPoint( m_bezierCtrl2X.GetValue(), m_bezierCtrl2Y.GetValue() ) );
  295. }
  296. }
  297. m_item->SetFilled( m_filledCtrl->GetValue() );
  298. m_item->SetWidth( m_thickness.GetValue() );
  299. m_item->SetLayer( ToLAYER_ID( layer ) );
  300. m_item->RebuildBezierToSegmentsPointsList( m_item->GetWidth() );
  301. commit.Push( _( "Modify drawing properties" ) );
  302. m_parent->UpdateMsgPanel();
  303. return true;
  304. }
  305. void DIALOG_GRAPHIC_ITEM_PROPERTIES::onLayer( wxCommandEvent& event )
  306. {
  307. if( m_item->GetShape() == S_POLYGON )
  308. {
  309. LSET graphicPolygonsLayers = LSET::AllLayersMask();
  310. graphicPolygonsLayers.reset( Edge_Cuts ).reset( F_CrtYd ).reset( B_CrtYd );
  311. m_filledCtrl->Enable( graphicPolygonsLayers.Contains(
  312. ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) ) );
  313. // Prevent courtyard/edge cuts from being filled
  314. if( !graphicPolygonsLayers.Contains(
  315. ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) ) )
  316. m_filledCtrl->SetValue( false );
  317. }
  318. }
  319. bool DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate()
  320. {
  321. wxArrayString error_msgs;
  322. if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() )
  323. return false;
  324. // Type specific checks.
  325. switch( m_item->GetShape() )
  326. {
  327. case S_ARC:
  328. // Check angle of arc.
  329. if( m_angle.GetValue() == 0 )
  330. error_msgs.Add( _( "The arc angle cannot be zero." ) );
  331. KI_FALLTHROUGH;
  332. case S_CIRCLE:
  333. // Check radius.
  334. if( m_startX.GetValue() == m_endX.GetValue() && m_startY.GetValue() == m_endY.GetValue() )
  335. error_msgs.Add( _( "The radius cannot be zero." ) );
  336. break;
  337. case S_RECT:
  338. // Check for null rect.
  339. if( m_startX.GetValue() == m_endX.GetValue() && m_startY.GetValue() == m_endY.GetValue() )
  340. error_msgs.Add( _( "The rectangle cannot be empty." ) );
  341. break;
  342. case S_POLYGON:
  343. case S_SEGMENT:
  344. case S_CURVE:
  345. break;
  346. default:
  347. wxASSERT_MSG( false, "DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate not implemented for shape"
  348. + PCB_SHAPE::ShowShape( m_item->GetShape() ) );
  349. break;
  350. }
  351. if( error_msgs.GetCount() )
  352. {
  353. HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
  354. dlg.ListSet( error_msgs );
  355. dlg.ShowModal();
  356. }
  357. return error_msgs.GetCount() == 0;
  358. }