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.

253 lines
7.0 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 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 pagelayout_editor/block.cpp
  25. * @brief Block operations
  26. */
  27. #include <fctsys.h>
  28. #include <common.h>
  29. #include <class_drawpanel.h>
  30. #include <pl_editor_frame.h>
  31. #include <worksheet_shape_builder.h>
  32. #include <worksheet_dataitem.h>
  33. static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
  34. bool erase );
  35. static void DrawMovingItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
  36. static void ConfigureDrawList( WS_DRAW_ITEM_LIST* aDrawList,
  37. PL_EDITOR_SCREEN* aScreen, PL_EDITOR_FRAME* aFrame );
  38. static void ConfigureDrawList( WS_DRAW_ITEM_LIST* aDrawList,
  39. PL_EDITOR_SCREEN* aScreen, PL_EDITOR_FRAME* aFrame )
  40. {
  41. aDrawList->SetPenSize( 0 );
  42. aDrawList->SetMilsToIUfactor( IU_PER_MILS );
  43. aDrawList->SetSheetNumber( aScreen->m_ScreenNumber );
  44. aDrawList->SetSheetCount( aScreen->m_NumberOfScreens );
  45. aDrawList->SetFileName( aFrame->GetCurrFileName() );
  46. aDrawList->SetSheetName( aFrame->GetScreenDesc() );
  47. aDrawList->BuildWorkSheetGraphicList( aFrame->GetPageSettings(),
  48. aFrame->GetTitleBlock(), RED, RED );
  49. }
  50. int PL_EDITOR_FRAME::BlockCommand( EDA_KEY key )
  51. {
  52. int cmd = 0;
  53. switch( key )
  54. {
  55. default:
  56. cmd = key & 0x255;
  57. break;
  58. case 0:
  59. cmd = BLOCK_MOVE;
  60. break;
  61. case GR_KB_SHIFT:
  62. case GR_KB_CTRL:
  63. case GR_KB_SHIFTCTRL:
  64. case GR_KB_ALT:
  65. break;
  66. case MOUSE_MIDDLE:
  67. cmd = BLOCK_ZOOM;
  68. break;
  69. }
  70. return cmd;
  71. }
  72. void PL_EDITOR_FRAME::HandleBlockPlace( wxDC* DC )
  73. {
  74. wxASSERT( m_canvas->IsMouseCaptured() );
  75. GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
  76. switch( GetScreen()->m_BlockLocate.GetCommand() )
  77. {
  78. case BLOCK_MOVE: /* Move */
  79. if( m_canvas->IsMouseCaptured() )
  80. m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
  81. Block_Move( DC );
  82. GetScreen()->m_BlockLocate.ClearItemsList();
  83. break;
  84. default:
  85. wxFAIL_MSG( wxT("HandleBlockPlace: Unexpected block command") );
  86. break;
  87. }
  88. m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
  89. GetScreen()->SetModify();
  90. GetScreen()->ClearBlockCommand();
  91. wxASSERT( GetScreen()->m_BlockLocate.GetCount() == 0 );
  92. DisplayToolMsg( wxEmptyString );
  93. }
  94. bool PL_EDITOR_FRAME::HandleBlockEnd( wxDC* DC )
  95. {
  96. bool nextcmd = false;
  97. bool zoom_command = false;
  98. if( m_canvas->IsMouseCaptured() )
  99. switch( GetScreen()->m_BlockLocate.GetCommand() )
  100. {
  101. case BLOCK_MOVE: /* Move */
  102. GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
  103. nextcmd = true;
  104. m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
  105. m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
  106. m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
  107. break;
  108. case BLOCK_ZOOM: /* Window Zoom */
  109. zoom_command = true;
  110. break;
  111. default:
  112. break;
  113. }
  114. if( ! nextcmd )
  115. {
  116. GetScreen()->ClearBlockCommand();
  117. m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
  118. false );
  119. }
  120. if( zoom_command )
  121. Window_Zoom( GetScreen()->m_BlockLocate );
  122. return nextcmd ;
  123. }
  124. static void DrawMovingItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
  125. {
  126. auto screen = static_cast<PL_EDITOR_SCREEN*>( aPanel->GetScreen() );
  127. auto frame = static_cast<PL_EDITOR_FRAME*>( aPanel->GetParent() );
  128. // Get items
  129. std::vector<WS_DRAW_ITEM_BASE*> items;
  130. WS_DRAW_ITEM_LIST drawList;
  131. ConfigureDrawList( &drawList, screen, frame );
  132. drawList.GetAllItems( &items );
  133. // Draw items
  134. for( auto item: items )
  135. {
  136. if( item->HitTest( screen->m_BlockLocate ) )
  137. {
  138. item->DrawWsItem( NULL, aDC, screen->m_BlockLocate.GetMoveVector(),
  139. g_XorMode, g_GhostColor );
  140. }
  141. }
  142. }
  143. /* Traces the outline of the block structures of a repositioning move
  144. */
  145. static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPositon,
  146. bool aErase )
  147. {
  148. auto screen = aPanel->GetScreen();
  149. auto block = &screen->m_BlockLocate;
  150. if( aErase )
  151. {
  152. block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
  153. DrawMovingItems( aPanel, aDC );
  154. }
  155. block->SetMoveVector( aPanel->GetParent()->GetCrossHairPosition() - block->GetLastCursorPosition() );
  156. block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
  157. DrawMovingItems( aPanel, aDC );
  158. }
  159. void PL_EDITOR_FRAME::Block_Move( wxDC* DC )
  160. {
  161. auto screen = static_cast<PL_EDITOR_SCREEN*>( GetScreen() );
  162. wxPoint delta;
  163. wxPoint oldpos;
  164. oldpos = GetCrossHairPosition();
  165. m_canvas->SetMouseCaptureCallback( NULL );
  166. SetCrossHairPosition( oldpos );
  167. m_canvas->MoveCursorToCrossHair();
  168. GetScreen()->SetModify();
  169. GetScreen()->m_BlockLocate.Normalize();
  170. // Calculate displacement vectors.
  171. delta = GetScreen()->m_BlockLocate.GetMoveVector();
  172. // Get the items
  173. std::vector<WS_DRAW_ITEM_BASE*> items;
  174. WS_DRAW_ITEM_LIST drawList;
  175. ConfigureDrawList( &drawList, screen, this );
  176. drawList.GetAllItems( &items );
  177. // Move items in block
  178. SaveCopyInUndoList();
  179. for( auto item: items )
  180. {
  181. auto parent = item->GetParent();
  182. if( parent )
  183. parent->ClearFlags( FLAG1 );
  184. }
  185. for( auto item: items )
  186. {
  187. if( item->HitTest( screen->m_BlockLocate ) )
  188. {
  189. auto data_item = item->GetParent();
  190. if( data_item && !( data_item->GetFlags() & FLAG1 ) )
  191. {
  192. data_item->SetFlags( FLAG1 );
  193. data_item->MoveToUi( data_item->GetStartPosUi() + delta );
  194. }
  195. }
  196. }
  197. m_canvas->Refresh( true );
  198. }