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.

296 lines
8.7 KiB

  1. /****************************************************/
  2. /* Routines de gestion des commandes sur blocks */
  3. /* (section commune eeschema/pcbnew... */
  4. /****************************************************/
  5. /* Fichier common.cpp */
  6. #include "fctsys.h"
  7. #include "gr_basic.h"
  8. #include "wxstruct.h"
  9. #include "common.h"
  10. #include "macros.h"
  11. /*******************/
  12. /* DrawBlockStruct */
  13. /*******************/
  14. /****************************************************************************/
  15. DrawBlockStruct::DrawBlockStruct() :
  16. EDA_BaseStruct( BLOCK_LOCATE_STRUCT_TYPE )
  17. , EDA_Rect()
  18. /****************************************************************************/
  19. {
  20. m_State = STATE_NO_BLOCK; /* Etat (enum BlockState) du block */
  21. m_Command = BLOCK_IDLE; /* Type (enum CmdBlockType) d'operation */
  22. m_BlockDrawStruct = NULL; /* pointeur sur la structure */
  23. m_Color = BROWN;
  24. }
  25. /****************************************/
  26. DrawBlockStruct::~DrawBlockStruct()
  27. /****************************************/
  28. {
  29. }
  30. /***************************************************************/
  31. void DrawBlockStruct::SetMessageBlock( WinEDA_DrawFrame* frame )
  32. /***************************************************************/
  33. /*
  34. * Print block command message (Block move, Block copy ...) in status bar
  35. */
  36. {
  37. wxString msg;
  38. switch( m_Command )
  39. {
  40. case BLOCK_IDLE:
  41. break;
  42. case BLOCK_MOVE: /* Move */
  43. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  44. msg = _( "Block Move" );
  45. break;
  46. case BLOCK_DRAG: /* Drag */
  47. msg = _( "Block Drag" );
  48. break;
  49. case BLOCK_COPY: /* Copy */
  50. msg = _( "Block Copy" );
  51. break;
  52. case BLOCK_DELETE: /* Delete */
  53. msg = _( "Block Delete" );
  54. break;
  55. case BLOCK_SAVE: /* Save */
  56. msg = _( "Block Save" );
  57. break;
  58. case BLOCK_PASTE:
  59. msg = _( "Block Paste" );
  60. break;
  61. case BLOCK_ZOOM: /* Window Zoom */
  62. msg = _( "Win Zoom" );
  63. break;
  64. case BLOCK_ROTATE: /* Rotate 90 deg */
  65. msg = _( "Block Rotate" );
  66. break;
  67. case BLOCK_INVERT: /* Flip */
  68. msg = _( "Block Invert" );
  69. break;
  70. case BLOCK_MIRROR_X:
  71. case BLOCK_MIRROR_Y: /* mirror */
  72. msg = _( "Block Mirror" );
  73. break;
  74. case BLOCK_ABORT:
  75. break;
  76. default:
  77. msg = wxT( "????" );
  78. break;
  79. }
  80. frame->DisplayToolMsg( msg );
  81. }
  82. /**************************************************************/
  83. void DrawBlockStruct::Draw( WinEDA_DrawPanel* panel, wxDC* DC )
  84. /**************************************************************/
  85. {
  86. int w = GetWidth() / panel->GetZoom();
  87. int h = GetHeight() / panel->GetZoom();
  88. if( w == 0 || h == 0 )
  89. GRLine( &panel->m_ClipBox, DC, GetX(), GetY(),
  90. GetRight(), GetBottom(), 0, m_Color );
  91. else
  92. GRRect( &panel->m_ClipBox, DC, GetX(), GetY(),
  93. GetRight(), GetBottom(), 0, m_Color );
  94. }
  95. /*************************************************************************/
  96. bool WinEDA_DrawFrame::HandleBlockBegin( wxDC* DC, int key,
  97. const wxPoint& startpos )
  98. /*************************************************************************/
  99. /* First command block function:
  100. * Init the Block infos: command type, initial position, and other variables..
  101. */
  102. {
  103. DrawBlockStruct* Block = & GetScreen()->BlockLocate;
  104. if( (Block->m_Command != BLOCK_IDLE)
  105. || ( Block->m_State != STATE_NO_BLOCK) )
  106. return FALSE;
  107. Block->m_Flags = 0;
  108. Block->m_Command = (CmdBlockType) ReturnBlockCommand( key );
  109. if( Block->m_Command == 0 )
  110. return FALSE;
  111. switch( Block->m_Command )
  112. {
  113. case BLOCK_IDLE:
  114. break;
  115. case BLOCK_MOVE: /* Move */
  116. case BLOCK_DRAG: /* Drag */
  117. case BLOCK_COPY: /* Copy */
  118. case BLOCK_DELETE: /* Delete */
  119. case BLOCK_SAVE: /* Save */
  120. case BLOCK_ROTATE: /* Rotate 90 deg */
  121. case BLOCK_INVERT: /* Flip */
  122. case BLOCK_ZOOM: /* Window Zoom */
  123. case BLOCK_MIRROR_X:
  124. case BLOCK_MIRROR_Y: /* mirror */
  125. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  126. InitBlockLocateDatas( DrawPanel, startpos );
  127. break;
  128. case BLOCK_PASTE:
  129. InitBlockLocateDatas( DrawPanel, startpos );
  130. Block->m_BlockLastCursorPosition.x = 0;
  131. Block->m_BlockLastCursorPosition.y = 0;
  132. InitBlockPasteInfos();
  133. if( Block->m_BlockDrawStruct == NULL ) /* No data to paste */
  134. {
  135. DisplayError( this, wxT( "No Block to paste" ), 20 );
  136. GetScreen()->BlockLocate.m_Command = BLOCK_IDLE;
  137. DrawPanel->ManageCurseur = NULL;
  138. return TRUE;
  139. }
  140. if( DrawPanel->ManageCurseur == NULL )
  141. {
  142. Block->m_BlockDrawStruct = NULL;
  143. DisplayError( this,
  144. wxT( "WinEDA_DrawFrame::HandleBlockBegin() Err: ManageCurseur NULL" ) );
  145. return TRUE;
  146. }
  147. Block->m_State = STATE_BLOCK_MOVE;
  148. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  149. break;
  150. default:
  151. {
  152. wxString msg;
  153. msg << wxT( "WinEDA_DrawFrame::HandleBlockBegin() error: Unknown command " ) <<
  154. Block->m_Command;
  155. DisplayError( this, msg );
  156. }
  157. break;
  158. }
  159. Block->SetMessageBlock( this );
  160. return TRUE;
  161. }
  162. /******************************************************************/
  163. void AbortBlockCurrentCommand( WinEDA_DrawPanel* Panel, wxDC* DC )
  164. /******************************************************************/
  165. /*
  166. * Cancel Current block operation.
  167. */
  168. {
  169. BASE_SCREEN* screen = Panel->GetScreen();
  170. if( Panel->ManageCurseur ) /* Erase current drawing on screen */
  171. {
  172. Panel->ManageCurseur( Panel, DC, FALSE ); /* Efface dessin fantome */
  173. Panel->ManageCurseur = NULL;
  174. Panel->ForceCloseManageCurseur = NULL;
  175. screen->SetCurItem( NULL );
  176. /* Delete the picked wrapper if this is a picked list. */
  177. if( (screen->BlockLocate.m_Command != BLOCK_PASTE)
  178. && screen->BlockLocate.m_BlockDrawStruct )
  179. {
  180. if( screen->BlockLocate.m_BlockDrawStruct->Type() == DRAW_PICK_ITEM_STRUCT_TYPE )
  181. {
  182. DrawPickedStruct* PickedList;
  183. PickedList = (DrawPickedStruct*) screen->BlockLocate.m_BlockDrawStruct;
  184. PickedList->DeleteWrapperList();
  185. }
  186. screen->BlockLocate.m_BlockDrawStruct = NULL;
  187. }
  188. }
  189. screen->BlockLocate.m_Flags = 0;
  190. screen->BlockLocate.m_State = STATE_NO_BLOCK;
  191. screen->BlockLocate.m_Command = BLOCK_ABORT;
  192. Panel->m_Parent->HandleBlockEnd( DC );
  193. screen->BlockLocate.m_Command = BLOCK_IDLE;
  194. Panel->m_Parent->DisplayToolMsg( wxEmptyString );
  195. }
  196. /*************************************************************************/
  197. void InitBlockLocateDatas( WinEDA_DrawPanel* Panel, const wxPoint& startpos )
  198. /*************************************************************************/
  199. /*
  200. * Init the initial values of a BlockLocate, before starting a block command
  201. */
  202. {
  203. BASE_SCREEN* screen = Panel->GetScreen();
  204. screen->BlockLocate.m_State = STATE_BLOCK_INIT;
  205. screen->BlockLocate.SetOrigin( startpos );
  206. screen->BlockLocate.SetSize( wxSize( 0, 0 ) );
  207. screen->BlockLocate.Pnext = NULL;
  208. screen->BlockLocate.m_BlockDrawStruct = NULL;
  209. Panel->ManageCurseur = DrawAndSizingBlockOutlines;
  210. Panel->ForceCloseManageCurseur = AbortBlockCurrentCommand;
  211. }
  212. /********************************************************************************/
  213. void DrawAndSizingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
  214. /********************************************************************************/
  215. /* Redraw the outlines of the block which shows the search area for block commands
  216. * The first point of the rectangle showing the area is initialised
  217. * by InitBlockLocateDatas().
  218. * The other point of the rectangle is the mouse cursor
  219. */
  220. {
  221. DrawBlockStruct* PtBlock;
  222. PtBlock = &panel->GetScreen()->BlockLocate;
  223. PtBlock->m_MoveVector = wxPoint( 0, 0 );
  224. GRSetDrawMode( DC, g_XorMode );
  225. /* Effacement ancien cadre */
  226. if( erase )
  227. PtBlock->Draw( panel, DC );
  228. PtBlock->m_BlockLastCursorPosition = panel->GetScreen()->m_Curseur;
  229. PtBlock->SetEnd( panel->GetScreen()->m_Curseur );
  230. PtBlock->Draw( panel, DC );
  231. if( PtBlock->m_State == STATE_BLOCK_INIT )
  232. {
  233. if( PtBlock->GetWidth() || PtBlock->GetHeight() )
  234. /* 2ieme point existant: le rectangle n'est pas de surface nulle */
  235. PtBlock->m_State = STATE_BLOCK_END;
  236. }
  237. }