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.

329 lines
9.6 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
  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. /**
  25. * @file edtxtmod.cpp
  26. * @brief Edit texts in footprints.
  27. */
  28. #include <fctsys.h>
  29. #include <gr_basic.h>
  30. #include <common.h>
  31. #include <class_drawpanel.h>
  32. #include <draw_graphic_text.h>
  33. #include <trigo.h>
  34. #include <pcb_base_frame.h>
  35. #include <macros.h>
  36. #include <pcbnew.h>
  37. #include <pcb_edit_frame.h>
  38. #include <footprint_edit_frame.h>
  39. #include <class_board.h>
  40. #include <class_module.h>
  41. #include <class_text_mod.h>
  42. #include <class_pcb_text.h>
  43. static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  44. bool aErase );
  45. static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
  46. wxPoint MoveVector; // Move vector for move edge, exported
  47. // to dialog_edit mod_text.cpp
  48. static wxPoint TextInitialPosition; // Mouse cursor initial position for
  49. // undo/abort move command
  50. static double TextInitialOrientation; // module text initial orientation for
  51. // undo/abort move+rot command+rot
  52. /* Add a new graphical text to the active module (footprint)
  53. * Note there always are 2 mandatory texts: reference and value.
  54. * New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
  55. */
  56. TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
  57. {
  58. TEXTE_MODULE* text = new TEXTE_MODULE( aModule );
  59. text->SetFlags( IS_NEW );
  60. if( LSET::AllTechMask().test( GetActiveLayer() ) ) // i.e. a possible layer for a text
  61. text->SetLayer( GetActiveLayer() );
  62. InstallTextOptionsFrame( text, NULL );
  63. if( text->GetText().IsEmpty() )
  64. {
  65. delete text;
  66. return NULL;
  67. }
  68. // Add the new text object to the beginning of the footprint draw list.
  69. if( aModule )
  70. aModule->GraphicalItemsList().PushFront( text );
  71. text->ClearFlags();
  72. if( aDC )
  73. text->Draw( m_canvas, aDC, GR_OR );
  74. SetMsgPanel( text );
  75. return text;
  76. }
  77. void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC )
  78. {
  79. if( Text == NULL )
  80. return;
  81. MODULE* module = (MODULE*) Text->GetParent();
  82. if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
  83. {
  84. if( IsType( FRAME_PCB ) )
  85. SaveCopyInUndoList( module, UR_CHANGED );
  86. }
  87. // we expect MoveVector to be (0,0) if there is no move in progress
  88. Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
  89. Text->SetTextAngle( Text->GetTextAngle() + 900 );
  90. Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
  91. SetMsgPanel( Text );
  92. if( module )
  93. module->SetLastEditTime();
  94. OnModify();
  95. }
  96. void PCB_BASE_FRAME::DeleteTextModule( TEXTE_MODULE* aText )
  97. {
  98. MODULE* module;
  99. if( aText == NULL )
  100. return;
  101. module = static_cast<MODULE*>( aText->GetParent() );
  102. if( aText->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
  103. {
  104. if( module && module->GetFlags() == 0 && aText->GetFlags() == 0 && IsType( FRAME_PCB ) )
  105. SaveCopyInUndoList( module, UR_CHANGED );
  106. m_canvas->RefreshDrawingRect( aText->GetBoundingBox() );
  107. aText->DeleteStructure();
  108. OnModify();
  109. module->SetLastEditTime();
  110. }
  111. }
  112. /**
  113. * Abort text move in progress.
  114. *
  115. * If a text is selected, its initial coordinates are regenerated.
  116. */
  117. static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
  118. {
  119. BASE_SCREEN* screen = Panel->GetScreen();
  120. TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
  121. MODULE* Module;
  122. Panel->SetMouseCapture( NULL, NULL );
  123. if( Text == NULL )
  124. return;
  125. Module = static_cast<MODULE*>( Text->GetParent() );
  126. Text->DrawUmbilical( Panel, DC, GR_XOR, -MoveVector );
  127. Text->Draw( Panel, DC, GR_XOR, MoveVector );
  128. // If the text was moved (the move does not change internal data)
  129. // it could be rotated while moving. So set old value for orientation
  130. if( Text->IsMoving() )
  131. Text->SetTextAngle( TextInitialOrientation );
  132. // Redraw the text
  133. Panel->RefreshDrawingRect( Text->GetBoundingBox() );
  134. // leave it at (0,0) so we can use it Rotate when not moving.
  135. MoveVector.x = MoveVector.y = 0;
  136. Text->ClearFlags();
  137. Module->ClearFlags();
  138. screen->SetCurItem( NULL );
  139. }
  140. void PCB_BASE_FRAME::StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC )
  141. {
  142. if( Text == NULL )
  143. return;
  144. MODULE *Module = static_cast<MODULE*>( Text->GetParent() );
  145. Text->SetFlags( IS_MOVED );
  146. Module->SetFlags( IN_EDIT );
  147. MoveVector.x = MoveVector.y = 0;
  148. TextInitialPosition = Text->GetTextPos();
  149. TextInitialOrientation = Text->GetTextAngle();
  150. // Center cursor on initial position of text
  151. SetCrossHairPosition( TextInitialPosition );
  152. m_canvas->MoveCursorToCrossHair();
  153. SetMsgPanel( Text );
  154. SetCurItem( Text );
  155. m_canvas->SetMouseCapture( Show_MoveTexte_Module, AbortMoveTextModule );
  156. m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
  157. }
  158. void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
  159. {
  160. if( Text != NULL )
  161. {
  162. m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
  163. Text->DrawUmbilical( m_canvas, DC, GR_XOR, -MoveVector );
  164. // Update the coordinates for anchor.
  165. MODULE* Module = static_cast<MODULE*>( Text->GetParent() );
  166. if( Module )
  167. {
  168. // Prepare undo command (a rotation can be made while moving)
  169. double tmp = Text->GetTextAngle();
  170. Text->SetTextAngle( TextInitialOrientation );
  171. if( IsType( FRAME_PCB ) )
  172. SaveCopyInUndoList( Module, UR_CHANGED );
  173. else
  174. SaveCopyInUndoList( Module, UR_CHANGED );
  175. Text->SetTextAngle( tmp );
  176. // Set the new position for text.
  177. Text->SetTextPos( GetCrossHairPosition() );
  178. wxPoint textRelPos = Text->GetTextPos() - Module->GetPosition();
  179. RotatePoint( &textRelPos, -Module->GetOrientation() );
  180. Text->SetPos0( textRelPos );
  181. Text->ClearFlags();
  182. Module->ClearFlags();
  183. Module->SetLastEditTime();
  184. OnModify();
  185. // Redraw text.
  186. m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
  187. }
  188. else
  189. {
  190. Text->SetTextPos( GetCrossHairPosition() );
  191. }
  192. }
  193. // leave it at (0,0) so we can use it Rotate when not moving.
  194. MoveVector.x = MoveVector.y = 0;
  195. m_canvas->SetMouseCapture( NULL, NULL );
  196. }
  197. static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  198. bool aErase )
  199. {
  200. BASE_SCREEN* screen = aPanel->GetScreen();
  201. TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
  202. if( Text == NULL )
  203. return;
  204. // Erase umbilical and text if necessary
  205. if( aErase )
  206. {
  207. Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
  208. Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
  209. }
  210. MoveVector = TextInitialPosition - aPanel->GetParent()->GetCrossHairPosition();
  211. // Draw umbilical if text moved
  212. if( MoveVector.x || MoveVector.y )
  213. Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
  214. // Redraw text
  215. Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
  216. }
  217. void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
  218. {
  219. wxSize newSize = GetDesignSettings().GetTextSize( aItem->GetLayer() );
  220. int newThickness = GetDesignSettings().GetTextThickness( aItem->GetLayer() );
  221. bool newItalic = GetDesignSettings().GetTextItalic( aItem->GetLayer() );
  222. if( aItem->Type() == PCB_TEXT_T )
  223. {
  224. TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem );
  225. // Exit if there's nothing to do
  226. if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
  227. return;
  228. SaveCopyInUndoList( text, UR_CHANGED );
  229. text->SetTextSize( newSize );
  230. text->SetThickness( newThickness );
  231. text->SetItalic( newItalic );
  232. }
  233. else if( aItem->Type() == PCB_MODULE_TEXT_T )
  234. {
  235. TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
  236. // Exit if there's nothing to do
  237. if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
  238. return;
  239. SaveCopyInUndoList( text->GetParent(), UR_CHANGED );
  240. text->SetTextSize( newSize );
  241. text->SetThickness( newThickness );
  242. text->SetItalic( newItalic );
  243. }
  244. else
  245. return;
  246. if( aDC )
  247. m_canvas->Refresh();
  248. OnModify();
  249. }