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.

352 lines
10 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file block_libedit.cpp
  27. */
  28. #include <fctsys.h>
  29. #include <gr_basic.h>
  30. #include <class_drawpanel.h>
  31. #include <confirm.h>
  32. #include <general.h>
  33. #include <class_library.h>
  34. #include <protos.h>
  35. #include <libeditframe.h>
  36. static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  37. bool aErase );
  38. int LIB_EDIT_FRAME::ReturnBlockCommand( int key )
  39. {
  40. int cmd = BLOCK_IDLE;
  41. switch( key )
  42. {
  43. default:
  44. cmd = key & 0x255;
  45. break;
  46. case -1:
  47. cmd = BLOCK_PRESELECT_MOVE;
  48. break;
  49. case 0:
  50. cmd = BLOCK_MOVE;
  51. break;
  52. case GR_KB_SHIFT:
  53. cmd = BLOCK_COPY;
  54. break;
  55. case GR_KB_ALT:
  56. cmd = BLOCK_ROTATE;
  57. break;
  58. case GR_KB_SHIFTCTRL:
  59. cmd = BLOCK_DELETE;
  60. break;
  61. case GR_KB_CTRL:
  62. cmd = BLOCK_MIRROR_Y;
  63. break;
  64. case MOUSE_MIDDLE:
  65. cmd = BLOCK_ZOOM;
  66. break;
  67. }
  68. return cmd;
  69. }
  70. bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
  71. {
  72. int ItemCount = 0;
  73. int nextCmd = false;
  74. wxPoint pt;
  75. if( GetScreen()->m_BlockLocate.GetCount() )
  76. {
  77. BLOCK_STATE_T state = GetScreen()->m_BlockLocate.GetState();
  78. BLOCK_COMMAND_T command = GetScreen()->m_BlockLocate.GetCommand();
  79. m_canvas->CallEndMouseCapture( DC );
  80. GetScreen()->m_BlockLocate.SetState( state );
  81. GetScreen()->m_BlockLocate.SetCommand( command );
  82. m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
  83. GetScreen()->SetCrossHairPosition( wxPoint( GetScreen()->m_BlockLocate.GetRight(),
  84. GetScreen()->m_BlockLocate.GetBottom() ) );
  85. m_canvas->MoveCursorToCrossHair();
  86. }
  87. switch( GetScreen()->m_BlockLocate.GetCommand() )
  88. {
  89. case BLOCK_IDLE:
  90. DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
  91. break;
  92. case BLOCK_DRAG: /* Drag */
  93. case BLOCK_MOVE: /* Move */
  94. case BLOCK_COPY: /* Copy */
  95. if ( m_component )
  96. ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
  97. m_unit, m_convert,
  98. m_editPinsPerPartOrConvert );
  99. if( ItemCount )
  100. {
  101. nextCmd = true;
  102. if( m_canvas->IsMouseCaptured() )
  103. {
  104. m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
  105. m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
  106. m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
  107. }
  108. GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
  109. m_canvas->Refresh( true );
  110. }
  111. break;
  112. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  113. nextCmd = true;
  114. m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
  115. GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
  116. break;
  117. case BLOCK_DELETE: /* Delete */
  118. if ( m_component )
  119. ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
  120. m_unit, m_convert,
  121. m_editPinsPerPartOrConvert );
  122. if( ItemCount )
  123. SaveCopyInUndoList( m_component );
  124. if ( m_component )
  125. {
  126. m_component->DeleteSelectedItems();
  127. OnModify();
  128. }
  129. break;
  130. case BLOCK_SAVE: /* Save */
  131. case BLOCK_PASTE:
  132. case BLOCK_FLIP:
  133. break;
  134. case BLOCK_ROTATE:
  135. case BLOCK_MIRROR_X:
  136. case BLOCK_MIRROR_Y:
  137. if ( m_component )
  138. ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate,
  139. m_unit, m_convert,
  140. m_editPinsPerPartOrConvert );
  141. if( ItemCount )
  142. SaveCopyInUndoList( m_component );
  143. pt = GetScreen()->m_BlockLocate.Centre();
  144. pt = GetScreen()->GetNearestGridPosition( pt );
  145. NEGATE( pt.y );
  146. if ( m_component )
  147. {
  148. OnModify();
  149. int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
  150. if( block_cmd == BLOCK_MIRROR_Y)
  151. m_component->MirrorSelectedItemsH( pt );
  152. else if( block_cmd == BLOCK_MIRROR_X)
  153. m_component->MirrorSelectedItemsV( pt );
  154. else if( block_cmd == BLOCK_ROTATE)
  155. m_component->RotateSelectedItems( pt );
  156. }
  157. break;
  158. case BLOCK_ZOOM: /* Window Zoom */
  159. Window_Zoom( GetScreen()->m_BlockLocate );
  160. break;
  161. case BLOCK_ABORT:
  162. break;
  163. case BLOCK_SELECT_ITEMS_ONLY:
  164. break;
  165. }
  166. if( ! nextCmd )
  167. {
  168. if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && m_component )
  169. m_component->ClearSelectedItems();
  170. GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
  171. GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
  172. GetScreen()->SetCurItem( NULL );
  173. m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
  174. false );
  175. m_canvas->Refresh( true );
  176. }
  177. return nextCmd;
  178. }
  179. void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
  180. {
  181. wxPoint pt;
  182. if( !m_canvas->IsMouseCaptured() )
  183. {
  184. DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
  185. }
  186. GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
  187. switch( GetScreen()->m_BlockLocate.GetCommand() )
  188. {
  189. case BLOCK_IDLE:
  190. break;
  191. case BLOCK_DRAG: /* Drag */
  192. case BLOCK_MOVE: /* Move */
  193. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  194. GetScreen()->m_BlockLocate.ClearItemsList();
  195. if ( m_component )
  196. SaveCopyInUndoList( m_component );
  197. pt = GetScreen()->m_BlockLocate.GetMoveVector();
  198. pt.y *= -1;
  199. if ( m_component )
  200. m_component->MoveSelectedItems( pt );
  201. m_canvas->Refresh( true );
  202. break;
  203. case BLOCK_COPY: /* Copy */
  204. GetScreen()->m_BlockLocate.ClearItemsList();
  205. if ( m_component )
  206. SaveCopyInUndoList( m_component );
  207. pt = GetScreen()->m_BlockLocate.GetMoveVector();
  208. NEGATE( pt.y );
  209. if ( m_component )
  210. m_component->CopySelectedItems( pt );
  211. break;
  212. case BLOCK_PASTE: /* Paste (recopy the last block saved) */
  213. GetScreen()->m_BlockLocate.ClearItemsList();
  214. break;
  215. case BLOCK_ROTATE: // Invert by popup menu, from block move
  216. case BLOCK_MIRROR_X: // Invert by popup menu, from block move
  217. case BLOCK_MIRROR_Y: // Invert by popup menu, from block move
  218. if ( m_component )
  219. SaveCopyInUndoList( m_component );
  220. pt = GetScreen()->m_BlockLocate.Centre();
  221. pt = GetScreen()->GetNearestGridPosition( pt );
  222. NEGATE( pt.y );
  223. if ( m_component )
  224. {
  225. int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
  226. if( block_cmd == BLOCK_MIRROR_Y)
  227. m_component->MirrorSelectedItemsH( pt );
  228. else if( block_cmd == BLOCK_MIRROR_X)
  229. m_component->MirrorSelectedItemsV( pt );
  230. else if( block_cmd == BLOCK_ROTATE )
  231. m_component->RotateSelectedItems( pt );
  232. }
  233. break;
  234. case BLOCK_ZOOM: // Handled by HandleBlockEnd
  235. case BLOCK_DELETE:
  236. case BLOCK_SAVE:
  237. case BLOCK_ABORT:
  238. default:
  239. break;
  240. }
  241. OnModify();
  242. GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
  243. GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
  244. GetScreen()->SetCurItem( NULL );
  245. m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
  246. m_canvas->Refresh( true );
  247. }
  248. /*
  249. * Traces the outline of the search block structures
  250. * The entire block follows the cursor
  251. */
  252. void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  253. bool aErase )
  254. {
  255. BLOCK_SELECTOR* block;
  256. BASE_SCREEN* screen = aPanel->GetScreen();
  257. wxPoint move_offset;
  258. block = &screen->m_BlockLocate;
  259. LIB_EDIT_FRAME* parent = ( LIB_EDIT_FRAME* ) aPanel->GetParent();
  260. wxASSERT( parent != NULL );
  261. LIB_COMPONENT* component = parent->GetComponent();
  262. if( component == NULL )
  263. return;
  264. int unit = parent->GetUnit();
  265. int convert = parent->GetConvert();
  266. if( aErase )
  267. {
  268. block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
  269. component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert,
  270. g_XorMode, UNSPECIFIED_COLOR, DefaultTransform, true, true, true );
  271. }
  272. // Repaint new view
  273. block->SetMoveVector( screen->GetCrossHairPosition() - block->GetLastCursorPosition() );
  274. GRSetDrawMode( aDC, g_XorMode );
  275. block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
  276. component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert,
  277. g_XorMode, UNSPECIFIED_COLOR, DefaultTransform, true, true, true );
  278. }