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.

561 lines
12 KiB

  1. /******************************************************************/
  2. /* drawpanel.cpp - fonctions des classes du type WinEDA_DrawPanel */
  3. /******************************************************************/
  4. #ifdef __GNUG__
  5. #pragma implementation
  6. #endif
  7. #include "fctsys.h"
  8. #include "common.h"
  9. /* defines locaux */
  10. #define CURSOR_SIZE 12 /* taille de la croix du curseur PCB */
  11. /*******************************************************/
  12. /* Class BASE_SCREEN: classe de gestion d'un affichage */
  13. /*******************************************************/
  14. BASE_SCREEN::BASE_SCREEN( int idscreen ) : EDA_BaseStruct( SCREEN_STRUCT_TYPE )
  15. {
  16. EEDrawList = NULL; /* Schematic items list */
  17. m_Type = idscreen;
  18. m_ZoomList = NULL;
  19. m_GridList = NULL;
  20. m_UndoList = NULL;
  21. m_RedoList = NULL;
  22. m_UndoRedoCountMax = 1;
  23. m_FirstRedraw = TRUE;
  24. InitDatas();
  25. }
  26. /******************************/
  27. BASE_SCREEN::~BASE_SCREEN( void )
  28. /******************************/
  29. {
  30. if( m_ZoomList )
  31. free( m_ZoomList );
  32. if( m_GridList )
  33. free( m_GridList );
  34. ClearUndoRedoList();
  35. }
  36. /*******************************/
  37. void BASE_SCREEN::InitDatas( void )
  38. /*******************************/
  39. {
  40. m_SheetNumber = m_NumberOfSheet = 1; /* gestion hierarchie: Root: SheetNumber = 1 */
  41. m_Zoom = 32;
  42. m_Grid = wxSize( 50, 50 ); /* pas de la grille */
  43. m_UserGrid = g_UserGrid; /* pas de la grille "utilisateur" */
  44. m_UserGridIsON = FALSE;
  45. m_UserGridUnit = g_UserGrid_Unit;
  46. m_Diviseur_Grille = 1;
  47. m_Center = TRUE;
  48. /* offsets pour tracer le circuit sur l'ecran */
  49. switch( m_Type ) // Init taille sheet par defaut
  50. {
  51. case SCHEMATIC_FRAME:
  52. m_Center = FALSE;
  53. m_CurrentSheet = &g_Sheet_A4;
  54. break;
  55. default:
  56. case CVPCB_DISPLAY_FRAME:
  57. case MODULE_EDITOR_FRAME:
  58. case PCB_FRAME:
  59. m_CurrentSheet = &g_Sheet_A4;
  60. break;
  61. case GERBER_FRAME:
  62. m_CurrentSheet = &g_Sheet_GERBER;
  63. break;
  64. }
  65. if( m_Center )
  66. {
  67. m_Curseur.x = m_Curseur.y = 0;
  68. m_DrawOrg.x = -ReturnPageSize().x / 2;
  69. m_DrawOrg.y = -ReturnPageSize().y / 2;
  70. }
  71. else
  72. {
  73. m_DrawOrg.x = m_DrawOrg.y = 0;
  74. m_Curseur.x = ReturnPageSize().x / 2;
  75. m_Curseur.y = ReturnPageSize().y / 2;
  76. }
  77. // DrawOrg est rendu multiple du zoom min :
  78. m_DrawOrg.x -= m_DrawOrg.x % 256;
  79. m_DrawOrg.y -= m_DrawOrg.y % 256;
  80. m_O_Curseur = m_Curseur;
  81. SetCurItem( NULL );
  82. /* indicateurs divers */
  83. m_FlagRefreshReq = 0; /* indique que l'ecran doit redessine */
  84. m_FlagModified = 0; // indique modif du PCB,utilise pour eviter une sortie sans sauvegarde
  85. m_FlagSave = 1; // indique sauvegarde auto faite
  86. }
  87. /******************************************************************/
  88. wxPoint BASE_SCREEN::CursorRealPosition( const wxPoint& ScreenPos )
  89. /******************************************************************/
  90. {
  91. wxPoint curpos;
  92. curpos.x = ScreenPos.x* GetZoom();
  93. curpos.y = ScreenPos.y* GetZoom();
  94. curpos.x += m_DrawOrg.x;
  95. curpos.y += m_DrawOrg.y;
  96. return curpos;
  97. }
  98. /***************************************/
  99. int BASE_SCREEN::GetInternalUnits( void )
  100. /***************************************/
  101. {
  102. switch( m_Type )
  103. {
  104. default:
  105. case SCHEMATIC_FRAME:
  106. return EESCHEMA_INTERNAL_UNIT;
  107. break;
  108. case GERBER_FRAME:
  109. case CVPCB_DISPLAY_FRAME:
  110. case MODULE_EDITOR_FRAME:
  111. case PCB_FRAME:
  112. return PCB_INTERNAL_UNIT;
  113. }
  114. }
  115. /*****************************************/
  116. wxSize BASE_SCREEN::ReturnPageSize( void )
  117. /*****************************************/
  118. /* Retourne en unites internes la taille de la feuille de dessin
  119. * (la taille de la feuille est connue en 1/1000 ")
  120. */
  121. {
  122. wxSize PageSize;
  123. switch( m_Type )
  124. {
  125. default:
  126. case SCHEMATIC_FRAME:
  127. PageSize = m_CurrentSheet->m_Size;
  128. break;
  129. case GERBER_FRAME:
  130. case CVPCB_DISPLAY_FRAME:
  131. case MODULE_EDITOR_FRAME:
  132. case PCB_FRAME:
  133. PageSize.x = m_CurrentSheet->m_Size.x * (PCB_INTERNAL_UNIT / 1000);
  134. PageSize.y = m_CurrentSheet->m_Size.y * (PCB_INTERNAL_UNIT / 1000);
  135. break;
  136. }
  137. return PageSize;
  138. }
  139. /********************************************/
  140. void BASE_SCREEN::SetZoomList( int* zoomlist )
  141. /********************************************/
  142. /* init liste des zoom (NULL terminated)
  143. */
  144. {
  145. int ii, nbitems, * zoom;
  146. // Decompte des items
  147. for( nbitems = 1, zoom = zoomlist; ; zoom++, nbitems++ )
  148. {
  149. if( *zoom == 0 )
  150. break;
  151. }
  152. // Init liste
  153. if( m_ZoomList )
  154. free( m_ZoomList );
  155. m_ZoomList = (int*) MyZMalloc( nbitems * sizeof( int) );
  156. for( ii = 0, zoom = zoomlist; ii < nbitems; zoom++, ii++ )
  157. {
  158. m_ZoomList[ii] = *zoom;
  159. }
  160. }
  161. /***********************************/
  162. void BASE_SCREEN::SetFirstZoom( void )
  163. /***********************************/
  164. /* ajuste le coeff de zoom a 1*/
  165. {
  166. m_Zoom = 1;
  167. }
  168. /****************************/
  169. int BASE_SCREEN::GetZoom( void )
  170. /****************************/
  171. /* retourne le coeff de zoom */
  172. {
  173. return m_Zoom;
  174. }
  175. /***********************************/
  176. void BASE_SCREEN::SetZoom( int coeff )
  177. /***********************************/
  178. /* ajuste le coeff de zoom a coeff */
  179. {
  180. m_Zoom = coeff;
  181. if( m_Zoom < 1 )
  182. m_Zoom = 1;
  183. }
  184. /********************************/
  185. void BASE_SCREEN::SetNextZoom( void )
  186. /********************************/
  187. /* Selectionne le prochain coeff de zoom
  188. */
  189. {
  190. m_Zoom *= 2;
  191. if( m_ZoomList == NULL )
  192. return;
  193. int ii, zoom_max = 512;
  194. for( ii = 0; m_ZoomList[ii] != 0; ii++ )
  195. zoom_max = m_ZoomList[ii];
  196. if( m_Zoom > zoom_max )
  197. m_Zoom = zoom_max;
  198. }
  199. /*************************************/
  200. void BASE_SCREEN::SetPreviousZoom( void )
  201. /*************************************/
  202. /* Selectionne le precedent coeff de zoom
  203. */
  204. {
  205. m_Zoom /= 2;
  206. if( m_Zoom < 1 )
  207. m_Zoom = 1;
  208. }
  209. /**********************************/
  210. void BASE_SCREEN::SetLastZoom( void )
  211. /**********************************/
  212. /* ajuste le coeff de zoom au max
  213. */
  214. {
  215. if( m_ZoomList == NULL )
  216. return;
  217. int ii;
  218. for( ii = 0; m_ZoomList[ii] != 0; ii++ )
  219. m_Zoom = m_ZoomList[ii];
  220. }
  221. /********************************************/
  222. void BASE_SCREEN::SetGridList( wxSize* gridlist )
  223. /********************************************/
  224. /* init liste des zoom (NULL terminated)
  225. */
  226. {
  227. int ii, nbitems;
  228. wxSize* grid;
  229. // Decompte des items
  230. for( nbitems = 0, grid = gridlist; ; grid++, nbitems++ )
  231. {
  232. if( (grid->x <= 0) || (grid->y <= 0) )
  233. break;
  234. }
  235. // Init liste
  236. if( m_GridList )
  237. free( m_GridList );
  238. m_GridList = (wxSize*) MyZMalloc( nbitems * sizeof(wxSize) );
  239. for( ii = 0, grid = gridlist; ii < nbitems; grid++, ii++ )
  240. {
  241. m_GridList[ii] = *grid;
  242. }
  243. }
  244. /**********************************************/
  245. void BASE_SCREEN::SetGrid( const wxSize& size )
  246. /**********************************************/
  247. {
  248. if( m_GridList == NULL )
  249. return;
  250. if( (size.x <= 0) || (size.y <= 0) )
  251. {
  252. m_UserGrid = g_UserGrid;
  253. m_UserGridIsON = TRUE;
  254. }
  255. else
  256. {
  257. m_Grid = size;
  258. m_UserGridIsON = FALSE;
  259. }
  260. }
  261. /*********************************/
  262. wxSize BASE_SCREEN::GetGrid( void )
  263. /*********************************/
  264. {
  265. wxSize grid = m_Grid;
  266. double xx, scale;
  267. if( m_GridList == NULL )
  268. return wxSize( 1, 1 );
  269. if( m_UserGridIsON || m_Grid.x < 0 || m_Grid.y < 0 )
  270. {
  271. if( m_UserGridUnit == INCHES )
  272. scale = 10000;
  273. else
  274. scale = 10000 / 25.4;
  275. xx = m_UserGrid.x * scale;
  276. grid.x = (int) (xx + 0.5);
  277. xx = m_UserGrid.y * scale;
  278. grid.y = (int) (xx + 0.5);
  279. }
  280. return grid;
  281. }
  282. /*********************************/
  283. void BASE_SCREEN::SetNextGrid( void )
  284. /*********************************/
  285. /* Selectionne la prochaine grille
  286. */
  287. {
  288. int ii;
  289. if( m_GridList == NULL )
  290. return;
  291. for( ii = 0; ; ii++ )
  292. {
  293. if( m_GridList[ii].x <= 0 )
  294. break;
  295. if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
  296. break;
  297. }
  298. if( (m_GridList[ii].x > 0) && (ii > 0) )
  299. m_Grid = m_GridList[ii - 1];
  300. }
  301. /*************************************/
  302. void BASE_SCREEN::SetPreviousGrid( void )
  303. /*************************************/
  304. /* Selectionne le precedent coeff de grille
  305. */
  306. {
  307. int ii;
  308. if( m_GridList == NULL )
  309. return;
  310. for( ii = 0; ; ii++ )
  311. {
  312. if( m_GridList[ii].x <= 0 )
  313. break;
  314. if( (m_Grid.x == m_GridList[ii].x) && (m_Grid.y == m_GridList[ii].y) )
  315. break;
  316. }
  317. if( (m_GridList[ii].x > 0) && (m_GridList[ii + 1].x > 0) )
  318. m_Grid = m_GridList[ii + 1];
  319. }
  320. /**********************************/
  321. void BASE_SCREEN::SetFirstGrid( void )
  322. /**********************************/
  323. /* ajuste le coeff de grille a 1
  324. */
  325. {
  326. if( m_GridList == NULL )
  327. return;
  328. int ii = 0;
  329. while( m_GridList[ii].x > 0 )
  330. ii++;
  331. m_Grid = m_GridList[ii - 1];
  332. }
  333. /**********************************/
  334. void BASE_SCREEN::SetLastGrid( void )
  335. /**********************************/
  336. /* ajuste le coeff de grille au max
  337. */
  338. {
  339. if( m_GridList == NULL )
  340. return;
  341. m_Grid = m_GridList[0];
  342. }
  343. /*****************************************/
  344. void BASE_SCREEN::ClearUndoRedoList( void )
  345. /*****************************************/
  346. /* free the undo and the redo lists
  347. */
  348. {
  349. EDA_BaseStruct* nextitem;
  350. while( m_UndoList )
  351. {
  352. nextitem = m_UndoList->Pnext;
  353. delete m_UndoList;
  354. m_UndoList = nextitem;
  355. }
  356. while( m_RedoList )
  357. {
  358. nextitem = m_RedoList->Pnext;
  359. delete m_RedoList;
  360. m_RedoList = nextitem;
  361. }
  362. }
  363. /***********************************************************/
  364. void BASE_SCREEN::AddItemToUndoList( EDA_BaseStruct* newitem )
  365. /************************************************************/
  366. /* Put newitem in head of undo list
  367. * Deletes olds items if > count max.
  368. */
  369. {
  370. int ii;
  371. EDA_BaseStruct* item, * nextitem;
  372. if( newitem == NULL )
  373. return;
  374. newitem->Pnext = m_UndoList;
  375. m_UndoList = newitem;
  376. /* Free first items, if count max reached */
  377. for( ii = 0, item = m_UndoList; ii < m_UndoRedoCountMax; ii++ )
  378. {
  379. if( item->Pnext == NULL )
  380. return;
  381. item = item->Pnext;
  382. }
  383. if( item == NULL )
  384. return;
  385. nextitem = item->Pnext;
  386. item->Pnext = NULL; // Set end of chain
  387. // Delete the extra items
  388. for( item = nextitem; item != NULL; item = nextitem )
  389. {
  390. nextitem = item->Pnext;
  391. delete item;
  392. }
  393. }
  394. /***********************************************************/
  395. void BASE_SCREEN::AddItemToRedoList( EDA_BaseStruct* newitem )
  396. /***********************************************************/
  397. {
  398. int ii;
  399. EDA_BaseStruct* item, * nextitem;
  400. if( newitem == NULL )
  401. return;
  402. newitem->Pnext = m_RedoList;
  403. m_RedoList = newitem;
  404. /* Free first items, if count max reached */
  405. for( ii = 0, item = m_RedoList; ii < m_UndoRedoCountMax; ii++ )
  406. {
  407. if( item->Pnext == NULL )
  408. break;
  409. item = item->Pnext;
  410. }
  411. if( item == NULL )
  412. return;
  413. nextitem = item->Pnext;
  414. item->Pnext = NULL; // Set end of chain
  415. // Delete the extra items
  416. for( item = nextitem; item != NULL; item = nextitem )
  417. {
  418. nextitem = item->Pnext;
  419. delete item;
  420. }
  421. }
  422. /*****************************************************/
  423. EDA_BaseStruct* BASE_SCREEN::GetItemFromUndoList( void )
  424. /*****************************************************/
  425. {
  426. EDA_BaseStruct* item = m_UndoList;
  427. if( item )
  428. m_UndoList = item->Pnext;
  429. return item;
  430. }
  431. /******************************************************/
  432. EDA_BaseStruct* BASE_SCREEN::GetItemFromRedoList( void )
  433. /******************************************************/
  434. {
  435. EDA_BaseStruct* item = m_RedoList;
  436. if( item )
  437. m_RedoList = item->Pnext;
  438. return item;
  439. }
  440. void BASE_SCREEN::SetCurItem( EDA_BaseStruct* aCurItem )
  441. {
  442. m_CurrentItem = aCurItem;
  443. }