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.

355 lines
10 KiB

18 years ago
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) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
  5. * Copyright (C) 1992-2012 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 module text.
  27. */
  28. #include <fctsys.h>
  29. #include <gr_basic.h>
  30. #include <common.h>
  31. #include <class_drawpanel.h>
  32. #include <drawtxt.h>
  33. #include <trigo.h>
  34. #include <wxBasePcbFrame.h>
  35. #include <macros.h>
  36. #include <pcbnew.h>
  37. #include <wxPcbStruct.h>
  38. #include <class_board.h>
  39. #include <class_module.h>
  40. #include <class_text_mod.h>
  41. #include <class_pcb_text.h>
  42. static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  43. bool aErase );
  44. static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
  45. wxPoint MoveVector; // Move vector for move edge, exported
  46. // to dialog_edit mod_text.cpp
  47. static wxPoint TextInitialPosition; // Mouse cursor initial position for
  48. // undo/abort move command
  49. static double TextInitialOrientation; // module text initial orientation for
  50. // undo/abort move+rot command+rot
  51. /* Add a new graphical text to the active module (footprint)
  52. * Note there always are 2 texts: reference and value.
  53. * New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
  54. */
  55. TEXTE_MODULE* PCB_BASE_FRAME::CreateTextModule( MODULE* Module, wxDC* DC )
  56. {
  57. TEXTE_MODULE* Text;
  58. Text = new TEXTE_MODULE( Module );
  59. /* Add the new text object to the beginning of the draw item list. */
  60. if( Module )
  61. Module->GraphicalItems().PushFront( Text );
  62. Text->SetFlags( IS_NEW );
  63. Text->SetText( wxT( "text" ) );
  64. GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth,
  65. std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
  66. Text->SetSize( GetDesignSettings().m_ModuleTextSize );
  67. Text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
  68. Text->SetTextPosition( GetScreen()->GetCrossHairPosition() );
  69. Text->SetLocalCoord();
  70. InstallTextModOptionsFrame( Text, NULL );
  71. m_canvas->MoveCursorToCrossHair();
  72. Text->ClearFlags();
  73. if( DC )
  74. Text->Draw( m_canvas, DC, GR_OR );
  75. SetMsgPanel( Text );
  76. return Text;
  77. }
  78. /* Rotate text 90 degrees.
  79. */
  80. void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC )
  81. {
  82. if( Text == NULL )
  83. return;
  84. MODULE* module = (MODULE*) Text->GetParent();
  85. if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
  86. {
  87. if( IsType( PCB_FRAME_TYPE ) )
  88. SaveCopyInUndoList( module, UR_CHANGED );
  89. }
  90. // we expect MoveVector to be (0,0) if there is no move in progress
  91. Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
  92. Text->SetOrientation( Text->GetOrientation() + 900 );
  93. Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
  94. SetMsgPanel( Text );
  95. if( module )
  96. module->SetLastEditTime();
  97. OnModify();
  98. }
  99. /*
  100. * Deletes text in module (if not the reference or value)
  101. */
  102. void PCB_BASE_FRAME::DeleteTextModule( TEXTE_MODULE* Text )
  103. {
  104. MODULE* Module;
  105. if( Text == NULL )
  106. return;
  107. Module = (MODULE*) Text->GetParent();
  108. if( Text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
  109. {
  110. m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
  111. Text->DeleteStructure();
  112. OnModify();
  113. Module->SetLastEditTime();
  114. }
  115. }
  116. /*
  117. * Abort text move in progress.
  118. *
  119. * If a text is selected, its initial coordinates are regenerated.
  120. */
  121. static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
  122. {
  123. BASE_SCREEN* screen = Panel->GetScreen();
  124. TEXTE_MODULE* Text = (TEXTE_MODULE*) screen->GetCurItem();
  125. MODULE* Module;
  126. Panel->SetMouseCapture( NULL, NULL );
  127. if( Text == NULL )
  128. return;
  129. Module = (MODULE*) Text->GetParent();
  130. Text->DrawUmbilical( Panel, DC, GR_XOR, -MoveVector );
  131. Text->Draw( Panel, DC, GR_XOR, MoveVector );
  132. // If the text was moved (the move does not change internal data)
  133. // it could be rotated while moving. So set old value for orientation
  134. if( Text->IsMoving() )
  135. Text->SetOrientation( TextInitialOrientation );
  136. /* Redraw the text */
  137. Panel->RefreshDrawingRect( Text->GetBoundingBox() );
  138. // leave it at (0,0) so we can use it Rotate when not moving.
  139. MoveVector.x = MoveVector.y = 0;
  140. Text->ClearFlags();
  141. Module->ClearFlags();
  142. screen->SetCurItem( NULL );
  143. }
  144. /* Start a text move.
  145. */
  146. void PCB_BASE_FRAME::StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC )
  147. {
  148. MODULE* Module;
  149. if( Text == NULL )
  150. return;
  151. Module = (MODULE*) Text->GetParent();
  152. Text->SetFlags( IS_MOVED );
  153. Module->SetFlags( IN_EDIT );
  154. MoveVector.x = MoveVector.y = 0;
  155. TextInitialPosition = Text->GetTextPosition();
  156. TextInitialOrientation = Text->GetOrientation();
  157. // Center cursor on initial position of text
  158. GetScreen()->SetCrossHairPosition( TextInitialPosition );
  159. m_canvas->MoveCursorToCrossHair();
  160. SetMsgPanel( Text );
  161. SetCurItem( Text );
  162. m_canvas->SetMouseCapture( Show_MoveTexte_Module, AbortMoveTextModule );
  163. m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
  164. }
  165. /* Place the text a the cursor position when the left mouse button is clicked.
  166. */
  167. void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
  168. {
  169. if( Text != NULL )
  170. {
  171. m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
  172. Text->DrawUmbilical( m_canvas, DC, GR_XOR, -MoveVector );
  173. /* Update the coordinates for anchor. */
  174. MODULE* Module = (MODULE*) Text->GetParent();
  175. if( Module )
  176. {
  177. // Prepare undo command (a rotation can be made while moving)
  178. double tmp = Text->GetOrientation();
  179. Text->SetOrientation( TextInitialOrientation );
  180. if( IsType( PCB_FRAME_TYPE ) )
  181. SaveCopyInUndoList( Module, UR_CHANGED );
  182. else
  183. SaveCopyInUndoList( Module, UR_MODEDIT );
  184. Text->SetOrientation( tmp );
  185. // Set the new position for text.
  186. Text->SetTextPosition( GetScreen()->GetCrossHairPosition() );
  187. wxPoint textRelPos = Text->GetTextPosition() - Module->GetPosition();
  188. RotatePoint( &textRelPos, -Module->GetOrientation() );
  189. Text->SetPos0( textRelPos );
  190. Text->ClearFlags();
  191. Module->ClearFlags();
  192. Module->SetLastEditTime();
  193. OnModify();
  194. /* Redraw text. */
  195. m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
  196. }
  197. else
  198. {
  199. Text->SetTextPosition( GetScreen()->GetCrossHairPosition() );
  200. }
  201. }
  202. // leave it at (0,0) so we can use it Rotate when not moving.
  203. MoveVector.x = MoveVector.y = 0;
  204. m_canvas->SetMouseCapture( NULL, NULL );
  205. }
  206. static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  207. bool aErase )
  208. {
  209. BASE_SCREEN* screen = aPanel->GetScreen();
  210. TEXTE_MODULE* Text = (TEXTE_MODULE*) screen->GetCurItem();
  211. if( Text == NULL )
  212. return;
  213. // Erase umbilical and text if necessary
  214. if( aErase )
  215. {
  216. Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
  217. Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
  218. }
  219. MoveVector = TextInitialPosition - screen->GetCrossHairPosition();
  220. // Draw umbilical if text moved
  221. if( MoveVector.x || MoveVector.y )
  222. Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
  223. // Redraw text
  224. Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
  225. }
  226. void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
  227. {
  228. wxSize newSize;
  229. int newThickness;
  230. TEXTE_PCB* pcbText = NULL;
  231. TEXTE_MODULE* moduleText = NULL;
  232. EDA_TEXT* text;
  233. switch( aItem->Type() )
  234. {
  235. case PCB_TEXT_T:
  236. newSize = GetDesignSettings().m_PcbTextSize;
  237. newThickness = GetDesignSettings().m_PcbTextWidth;
  238. pcbText = (TEXTE_PCB*) aItem;
  239. text = (EDA_TEXT*) pcbText;
  240. break;
  241. case PCB_MODULE_TEXT_T:
  242. newSize = GetDesignSettings().m_ModuleTextSize;
  243. newThickness = GetDesignSettings().m_ModuleTextWidth;
  244. moduleText = (TEXTE_MODULE*) aItem;
  245. text = (EDA_TEXT*) moduleText;
  246. break;
  247. default:
  248. // Exit if aItem is not a text field
  249. return;
  250. break;
  251. }
  252. // Exit if there's nothing to do
  253. if( text->GetSize() == newSize && text->GetThickness() == newThickness )
  254. return;
  255. // Push item to undo list
  256. switch( aItem->Type() )
  257. {
  258. case PCB_TEXT_T:
  259. SaveCopyInUndoList( pcbText, UR_CHANGED );
  260. break;
  261. case PCB_MODULE_TEXT_T:
  262. SaveCopyInUndoList( moduleText->GetParent(), UR_CHANGED );
  263. break;
  264. default:
  265. break;
  266. }
  267. // Apply changes
  268. text->SetSize( newSize );
  269. text->SetThickness( newThickness );
  270. if( aDC )
  271. RefreshCanvas();
  272. OnModify();
  273. }