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.

448 lines
13 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /*****************************************************************/
  2. /* Operations sur Blocks : deplacement, rotation, effacement ... */
  3. /*****************************************************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "gerbview.h"
  8. #include "trigo.h"
  9. #include "protos.h"
  10. #define BLOCK_COLOR BROWN
  11. /* Routines Locales */
  12. static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
  13. static TRACK* IsSegmentInBox( DrawBlockStruct& blocklocate, TRACK* PtSegm );
  14. /* Variables locales :*/
  15. /*************************************************/
  16. int WinEDA_GerberFrame::ReturnBlockCommand( int key )
  17. /*************************************************/
  18. /* Return the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
  19. * the key (ALT, SHIFT ALT ..)
  20. */
  21. {
  22. int cmd = 0;
  23. switch( key )
  24. {
  25. default:
  26. cmd = key & 0x255;
  27. break;
  28. case 0:
  29. cmd = BLOCK_MOVE;
  30. break;
  31. case GR_KB_SHIFT:
  32. break;
  33. case GR_KB_CTRL:
  34. break;
  35. case GR_KB_SHIFTCTRL:
  36. cmd = BLOCK_DELETE;
  37. break;
  38. case GR_KB_ALT:
  39. cmd = BLOCK_COPY;
  40. break;
  41. case MOUSE_MIDDLE:
  42. cmd = BLOCK_ZOOM;
  43. break;
  44. }
  45. return cmd;
  46. }
  47. /*****************************************************/
  48. void WinEDA_GerberFrame::HandleBlockPlace( wxDC* DC )
  49. /*****************************************************/
  50. /* Routine to handle the BLOCK PLACE commande */
  51. {
  52. bool err = FALSE;
  53. if( DrawPanel->ManageCurseur == NULL )
  54. {
  55. err = TRUE;
  56. DisplayError( this, wxT( "Error in HandleBlockPLace : ManageCurseur = NULL" ) );
  57. }
  58. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  59. switch( GetScreen()->BlockLocate.m_Command )
  60. {
  61. case BLOCK_IDLE:
  62. err = TRUE;
  63. break;
  64. case BLOCK_DRAG: /* Drag */
  65. case BLOCK_MOVE: /* Move */
  66. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  67. if( DrawPanel->ManageCurseur )
  68. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  69. Block_Move( DC );
  70. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  71. break;
  72. case BLOCK_COPY: /* Copy */
  73. if( DrawPanel->ManageCurseur )
  74. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  75. Block_Duplicate( DC );
  76. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  77. break;
  78. case BLOCK_PASTE:
  79. break;
  80. case BLOCK_ZOOM: // Handle by HandleBlockEnd()
  81. case BLOCK_ROTATE:
  82. case BLOCK_INVERT:
  83. case BLOCK_DELETE:
  84. case BLOCK_SAVE:
  85. case BLOCK_ABORT:
  86. case BLOCK_SELECT_ITEMS_ONLY:
  87. case BLOCK_MIRROR_X:
  88. case BLOCK_MIRROR_Y:
  89. break;
  90. }
  91. GetScreen()->SetModify();
  92. DrawPanel->ManageCurseur = NULL;
  93. DrawPanel->ForceCloseManageCurseur = NULL;
  94. GetScreen()->BlockLocate.m_Flags = 0;
  95. GetScreen()->BlockLocate.m_State = STATE_NO_BLOCK;
  96. GetScreen()->BlockLocate.m_Command = BLOCK_IDLE;
  97. if( GetScreen()->BlockLocate.m_BlockDrawStruct )
  98. {
  99. DisplayError( this, wxT( "Error in HandleBlockPLace DrawStruct != NULL" ) );
  100. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  101. }
  102. DisplayToolMsg( wxEmptyString );
  103. }
  104. /**********************************************/
  105. int WinEDA_GerberFrame::HandleBlockEnd( wxDC* DC )
  106. /**********************************************/
  107. /* Routine de gestion de la commande BLOCK END
  108. * returne :
  109. * 0 si aucun compos ant selectionne
  110. * 1 sinon
  111. * -1 si commande termine et composants trouvs (block delete, block save)
  112. */
  113. {
  114. int endcommande = TRUE;
  115. bool zoom_command = FALSE;
  116. if( DrawPanel->ManageCurseur )
  117. switch( GetScreen()->BlockLocate.m_Command )
  118. {
  119. case BLOCK_IDLE:
  120. DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
  121. break;
  122. case BLOCK_DRAG: /* Drag (not used, for future enhancements)*/
  123. case BLOCK_MOVE: /* Move */
  124. case BLOCK_COPY: /* Copy */
  125. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  126. GetScreen()->BlockLocate.m_State = STATE_BLOCK_MOVE;
  127. endcommande = FALSE;
  128. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  129. DrawPanel->ManageCurseur = DrawMovingBlockOutlines;
  130. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  131. break;
  132. case BLOCK_DELETE: /* Delete */
  133. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  134. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  135. Block_Delete( DC );
  136. break;
  137. case BLOCK_ROTATE: /* Unused */
  138. break;
  139. case BLOCK_INVERT: /* Fip */
  140. break;
  141. case BLOCK_SAVE: /* Save (not used)*/
  142. break;
  143. case BLOCK_PASTE:
  144. break;
  145. case BLOCK_ZOOM: /* Window Zoom */
  146. zoom_command = TRUE;
  147. break;
  148. case BLOCK_ABORT:
  149. case BLOCK_SELECT_ITEMS_ONLY:
  150. case BLOCK_MIRROR_X:
  151. case BLOCK_MIRROR_Y:
  152. break;
  153. }
  154. if( endcommande == TRUE )
  155. {
  156. GetScreen()->BlockLocate.m_Flags = 0;
  157. GetScreen()->BlockLocate.m_State = STATE_NO_BLOCK;
  158. GetScreen()->BlockLocate.m_Command = BLOCK_IDLE;
  159. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  160. DrawPanel->ManageCurseur = NULL;
  161. DrawPanel->ForceCloseManageCurseur = NULL;
  162. DisplayToolMsg( wxEmptyString );
  163. }
  164. if( zoom_command )
  165. Window_Zoom( GetScreen()->BlockLocate );
  166. return endcommande;
  167. }
  168. /**************************************************************************/
  169. static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
  170. /**************************************************************************/
  171. /* Retrace le contour du block de repositionnement des structures a d�placer
  172. */
  173. {
  174. int Color;
  175. BASE_SCREEN* screen = panel->GetScreen();
  176. Color = YELLOW; GRSetDrawMode( DC, g_XorMode );
  177. /* Effacement ancien cadre */
  178. if( erase )
  179. {
  180. screen->BlockLocate.Draw( panel, DC );
  181. if( screen->BlockLocate.m_MoveVector.x || screen->BlockLocate.m_MoveVector.y )
  182. {
  183. screen->BlockLocate.Offset( screen->BlockLocate.m_MoveVector );
  184. screen->BlockLocate.Draw( panel, DC );
  185. screen->BlockLocate.Offset( -screen->BlockLocate.m_MoveVector.x,
  186. -screen->BlockLocate.m_MoveVector.y );
  187. }
  188. }
  189. if( panel->GetScreen()->BlockLocate.m_State != STATE_BLOCK_STOP )
  190. {
  191. screen->BlockLocate.m_MoveVector.x = screen->m_Curseur.x - screen->BlockLocate.GetRight();
  192. screen->BlockLocate.m_MoveVector.y = screen->m_Curseur.y - screen->BlockLocate.GetBottom();
  193. }
  194. screen->BlockLocate.Draw( panel, DC );
  195. if( screen->BlockLocate.m_MoveVector.x || screen->BlockLocate.m_MoveVector.y )
  196. {
  197. screen->BlockLocate.Offset( screen->BlockLocate.m_MoveVector );
  198. screen->BlockLocate.Draw( panel, DC );
  199. screen->BlockLocate.Offset( -screen->BlockLocate.m_MoveVector.x,
  200. -screen->BlockLocate.m_MoveVector.y );
  201. }
  202. }
  203. /************************************************/
  204. void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
  205. /************************************************/
  206. /*
  207. * routine d'effacement du block deja selectionne
  208. */
  209. {
  210. if( !IsOK( this, _( "Ok to delete block ?" ) ) )
  211. return;
  212. GetScreen()->SetModify();
  213. GetScreen()->BlockLocate.Normalize();
  214. GetScreen()->SetCurItem( NULL );
  215. /* Effacement des Pistes */
  216. TRACK* pt_segm, * NextS;
  217. for( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = NextS )
  218. {
  219. NextS = pt_segm->Next();
  220. if( IsSegmentInBox( GetScreen()->BlockLocate, pt_segm ) )
  221. {
  222. /* la piste est ici bonne a etre efface */
  223. pt_segm->Draw( DrawPanel, DC, GR_XOR );
  224. pt_segm->DeleteStructure();
  225. }
  226. }
  227. /* Effacement des Zones */
  228. for( pt_segm = m_Pcb->m_Zone; pt_segm != NULL; pt_segm = NextS )
  229. {
  230. NextS = pt_segm->Next();
  231. if( IsSegmentInBox( GetScreen()->BlockLocate, pt_segm ) )
  232. {
  233. /* la piste est ici bonne a etre efface */
  234. pt_segm->Draw( DrawPanel, DC, GR_XOR );
  235. pt_segm->DeleteStructure();
  236. }
  237. }
  238. /* Rafraichissement de l'ecran : */
  239. RedrawActiveWindow( DC, TRUE );
  240. }
  241. /************************************************/
  242. void WinEDA_BasePcbFrame::Block_Move( wxDC* DC )
  243. /************************************************/
  244. /*
  245. * Function to move items in the current selected block
  246. */
  247. {
  248. wxPoint delta;
  249. wxPoint oldpos;
  250. oldpos = GetScreen()->m_Curseur;
  251. DrawPanel->ManageCurseur = NULL;
  252. GetScreen()->m_Curseur = oldpos;
  253. DrawPanel->MouseToCursorSchema();
  254. GetScreen()->SetModify();
  255. GetScreen()->BlockLocate.Normalize();
  256. /* calcul du vecteur de deplacement pour les deplacements suivants */
  257. delta = GetScreen()->BlockLocate.m_MoveVector;
  258. /* Move the Track segments in block */
  259. TRACK* track = m_Pcb->m_Track;
  260. while( track )
  261. {
  262. if( IsSegmentInBox( GetScreen()->BlockLocate, track ) )
  263. {
  264. m_Pcb->m_Status_Pcb = 0;
  265. track->Draw( DrawPanel, DC, GR_XOR ); // erase the display
  266. track->m_Start += delta;
  267. track->m_End += delta;
  268. // the two parameters are used in gerbview to store centre coordinates for arcs.
  269. // move this centre
  270. track->m_Param += delta.x;
  271. track->SetSubNet( track->GetSubNet() + delta.y );
  272. track->Draw( DrawPanel, DC, GR_OR ); // redraw the moved track
  273. }
  274. track = track->Next();
  275. }
  276. /* Move the Zone segments in block */
  277. SEGZONE * zsegment= m_Pcb->m_Zone;
  278. while( zsegment )
  279. {
  280. if( IsSegmentInBox( GetScreen()->BlockLocate, zsegment ) )
  281. {
  282. zsegment->Draw( DrawPanel, DC, GR_XOR ); // erase the display
  283. zsegment->m_Start += delta;
  284. zsegment->m_End += delta;
  285. // the two parameters are used in gerbview to store centre coordinates for arcs.
  286. // move this centre
  287. zsegment->m_Param += delta.x;
  288. zsegment->SetSubNet( zsegment->GetSubNet() + delta.y );
  289. zsegment->Draw( DrawPanel, DC, GR_OR ); // redraw the moved zone zegment
  290. }
  291. zsegment = zsegment->Next();
  292. }
  293. DrawPanel->Refresh( TRUE );
  294. }
  295. /**************************************************/
  296. void WinEDA_BasePcbFrame::Block_Duplicate( wxDC* DC )
  297. /**************************************************/
  298. /*
  299. * Function to duplicate items in the current selected block
  300. */
  301. {
  302. wxPoint delta;
  303. wxPoint oldpos;
  304. oldpos = GetScreen()->m_Curseur;
  305. DrawPanel->ManageCurseur = NULL;
  306. GetScreen()->m_Curseur = oldpos;
  307. DrawPanel->MouseToCursorSchema();
  308. GetScreen()->SetModify();
  309. GetScreen()->BlockLocate.Normalize();
  310. /* calcul du vecteur de deplacement pour les deplacements suivants */
  311. delta = GetScreen()->BlockLocate.m_MoveVector;
  312. /* Copy selected track segments and move the new track its new location */
  313. TRACK* track = m_Pcb->m_Track;
  314. while( track )
  315. {
  316. TRACK* next_track = track->Next();
  317. if( IsSegmentInBox( GetScreen()->BlockLocate, track ) )
  318. {
  319. /* this track segment must be duplicated */
  320. m_Pcb->m_Status_Pcb = 0;
  321. TRACK* new_track = track->Copy();
  322. new_track->Insert( m_Pcb, NULL );
  323. new_track->m_Start += delta;
  324. new_track->m_End += delta;
  325. new_track->Draw( DrawPanel, DC, GR_OR ); // draw the new created segment
  326. }
  327. track = next_track;
  328. }
  329. /* Copy the Zone segments and move the new segment to its new location */
  330. SEGZONE * zsegment= m_Pcb->m_Zone;
  331. while( zsegment )
  332. {
  333. SEGZONE * next_zsegment = zsegment->Next();
  334. if( IsSegmentInBox( GetScreen()->BlockLocate, zsegment ) )
  335. {
  336. /* this zone segment must be duplicated */
  337. SEGZONE * new_zsegment = (SEGZONE*) zsegment->Copy();
  338. new_zsegment->Insert( m_Pcb, NULL );
  339. new_zsegment->m_Start += delta;
  340. new_zsegment->m_End += delta;
  341. new_zsegment->Draw( DrawPanel, DC, GR_OR ); // draw the new created segment
  342. }
  343. zsegment = next_zsegment;
  344. }
  345. }
  346. /**************************************************************************/
  347. static TRACK* IsSegmentInBox( DrawBlockStruct& blocklocate, TRACK* PtSegm )
  348. /**************************************************************************/
  349. /* Teste si la structure PtStruct est inscrite dans le block selectionne
  350. * Retourne PtSegm si oui
  351. * NULL si non
  352. */
  353. {
  354. if( blocklocate.Inside( PtSegm->m_Start.x, PtSegm->m_Start.y ) )
  355. return PtSegm;
  356. if( blocklocate.Inside( PtSegm->m_End.x, PtSegm->m_End.y ) )
  357. return PtSegm;
  358. return NULL;
  359. }