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.

508 lines
18 KiB

17 years ago
17 years ago
17 years ago
17 years ago
17 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.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 class_base_screen.h
  27. * @brief BASE_SCREEN class implementation.
  28. */
  29. #ifndef CLASS_BASE_SCREEN_H_
  30. #define CLASS_BASE_SCREEN_H_
  31. #include <draw_frame.h>
  32. #include <base_struct.h>
  33. #include <class_undoredo_container.h>
  34. #include <block_commande.h>
  35. #include <common.h>
  36. #include <id.h>
  37. /**
  38. * Class GRID_TYPE
  39. * is for grid arrays.
  40. */
  41. class GRID_TYPE
  42. {
  43. public:
  44. int m_CmdId; // The command id of this grid ( first id is ID_POPUP_GRID_LEVEL_1000 )
  45. wxRealPoint m_Size; // the size in internal unit of the grid (can differ for X and Y axis)
  46. GRID_TYPE& operator=( const GRID_TYPE& item )
  47. {
  48. if( this != &item )
  49. {
  50. m_CmdId = item.m_CmdId;
  51. m_Size = item.m_Size;
  52. }
  53. return *this;
  54. }
  55. const bool operator==( const GRID_TYPE& item ) const
  56. {
  57. return m_Size == item.m_Size && m_CmdId == item.m_CmdId;
  58. }
  59. };
  60. typedef std::vector<GRID_TYPE> GRIDS;
  61. /**
  62. * Class BASE_SCREEN
  63. * handles how to draw a screen (a board, a schematic ...)
  64. */
  65. class BASE_SCREEN : public EDA_ITEM
  66. {
  67. private:
  68. GRIDS m_grids; ///< List of valid grid sizes.
  69. bool m_FlagModified; ///< Indicates current drawing has been modified.
  70. bool m_FlagSave; ///< Indicates automatic file save.
  71. EDA_ITEM* m_CurrentItem; ///< Currently selected object
  72. GRID_TYPE m_Grid; ///< Current grid selection.
  73. wxPoint m_scrollCenter; ///< Current scroll center point in logical units.
  74. wxPoint m_MousePosition; ///< Mouse cursor coordinate in logical units.
  75. int m_UndoRedoCountMax; ///< undo/Redo command Max depth
  76. /**
  77. * The cross hair position in logical (drawing) units. The cross hair is not the cursor
  78. * position. It is an addition indicator typically drawn on grid to indicate to the
  79. * user where the current action will be performed.
  80. */
  81. wxPoint m_crossHairPosition;
  82. double m_Zoom; ///< Current zoom coefficient.
  83. //----< Old public API now is private, and migratory>------------------------
  84. // called only from EDA_DRAW_FRAME
  85. friend class EDA_DRAW_FRAME;
  86. /**
  87. * Function getCrossHairPosition
  88. * return the current cross hair position in logical (drawing) coordinates.
  89. * @param aInvertY Inverts the Y axis position.
  90. * @return The cross hair position in drawing coordinates.
  91. */
  92. wxPoint getCrossHairPosition( bool aInvertY ) const
  93. {
  94. if( aInvertY )
  95. return wxPoint( m_crossHairPosition.x, -m_crossHairPosition.y );
  96. return wxPoint( m_crossHairPosition.x, m_crossHairPosition.y );
  97. }
  98. /**
  99. * Function setCrossHairPosition
  100. * sets the screen cross hair position to \a aPosition in logical (drawing) units.
  101. * @param aPosition The new cross hair position.
  102. * @param aGridOrigin Origin point of the snap grid.
  103. * @param aSnapToGrid Sets the cross hair position to the nearest grid position to
  104. * \a aPosition.
  105. *
  106. */
  107. void setCrossHairPosition( const wxPoint& aPosition, const wxPoint& aGridOrigin, bool aSnapToGrid );
  108. /**
  109. * Function getCursorScreenPosition
  110. * returns the cross hair position in device (display) units.b
  111. * @return The current cross hair position.
  112. */
  113. wxPoint getCrossHairScreenPosition() const;
  114. /**
  115. * Function getNearestGridPosition
  116. * returns the nearest \a aGridSize location to \a aPosition.
  117. * @param aPosition The position to check.
  118. * @param aGridOrigin The origin point of the snap grid.
  119. * @param aGridSize The grid size to locate to if provided. If NULL then the current
  120. * grid size is used.
  121. * @return The nearst grid position.
  122. */
  123. wxPoint getNearestGridPosition( const wxPoint& aPosition, const wxPoint& aGridOrigin,
  124. wxRealPoint* aGridSize ) const;
  125. /**
  126. * Function getCursorPosition
  127. * returns the current cursor position in logical (drawing) units.
  128. * @param aOnGrid Returns the nearest grid position at the current cursor position.
  129. * @param aGridOrigin Origin point of the snap grid.
  130. * @param aGridSize Custom grid size instead of the current grid size. Only valid
  131. * if \a aOnGrid is true.
  132. * @return The current cursor position.
  133. */
  134. wxPoint getCursorPosition( bool aOnGrid, const wxPoint& aGridOrigin, wxRealPoint* aGridSize ) const;
  135. void setMousePosition( const wxPoint& aPosition ) { m_MousePosition = aPosition; }
  136. /**
  137. * Function RefPos
  138. * Return the reference position, coming from either the mouse position
  139. * or the cursor position.
  140. *
  141. * @param useMouse If true, return mouse position, else cursor's.
  142. *
  143. * @return wxPoint - The reference point, either the mouse position or
  144. * the cursor position.
  145. */
  146. wxPoint refPos( bool useMouse ) const
  147. {
  148. return useMouse ? m_MousePosition : m_crossHairPosition;
  149. }
  150. const wxPoint& getScrollCenterPosition() const { return m_scrollCenter; }
  151. void setScrollCenterPosition( const wxPoint& aPoint ) { m_scrollCenter = aPoint; }
  152. //----</Old public API now is private, and migratory>------------------------
  153. public:
  154. static wxString m_PageLayoutDescrFileName; ///< the name of the page layout descr file,
  155. ///< or emty to used the default pagelayout
  156. wxPoint m_DrawOrg; ///< offsets for drawing the circuit on the screen
  157. wxPoint m_O_Curseur; ///< Relative Screen cursor coordinate (on grid)
  158. ///< in user units. (coordinates from last reset position)
  159. // Scrollbars management:
  160. int m_ScrollPixelsPerUnitX; ///< Pixels per scroll unit in the horizontal direction.
  161. int m_ScrollPixelsPerUnitY; ///< Pixels per scroll unit in the vertical direction.
  162. wxSize m_ScrollbarNumber; /**< Current virtual draw area size in scroll units.
  163. * m_ScrollbarNumber * m_ScrollPixelsPerUnit =
  164. * virtual draw area size in pixels */
  165. wxPoint m_ScrollbarPos; ///< Current scroll bar position in scroll units.
  166. wxPoint m_StartVisu; /**< Coordinates in drawing units of the current
  167. * view position (upper left corner of device)
  168. */
  169. bool m_Center; /**< Center on screen. If true (0.0) is centered
  170. * on screen coordinates can be < 0 and
  171. * > 0 except for schematics.
  172. * false: when coordinates can only be >= 0
  173. * Schematic */
  174. bool m_FirstRedraw;
  175. // Undo/redo list of commands
  176. UNDO_REDO_CONTAINER m_UndoList; ///< Objects list for the undo command (old data)
  177. UNDO_REDO_CONTAINER m_RedoList; ///< Objects list for the redo command (old data)
  178. // block control
  179. BLOCK_SELECTOR m_BlockLocate; ///< Block description for block commands
  180. int m_ScreenNumber;
  181. int m_NumberOfScreens;
  182. std::vector<double> m_ZoomList; ///< standard zoom (i.e. scale) coefficients.
  183. bool m_IsPrinting;
  184. public:
  185. BASE_SCREEN( KICAD_T aType = SCREEN_T );
  186. ~BASE_SCREEN();
  187. /**
  188. * Function SetCurItem
  189. * sets the currently selected object, m_CurrentItem.
  190. * @param aItem Any object derived from EDA_ITEM
  191. */
  192. void SetCurItem( EDA_ITEM* aItem ) { m_CurrentItem = aItem; }
  193. EDA_ITEM* GetCurItem() const { return m_CurrentItem; }
  194. void InitDataPoints( const wxSize& aPageSizeInternalUnits );
  195. /**
  196. * Function MilsToIuScalar
  197. * returns the scalar required to convert mils to internal units.
  198. *
  199. * @note This is a temporary hack until the derived objects SCH_SCREEN and PCB_SCREEN
  200. * no longer need to be derived from BASE_SCREEN. I does allow removal of the
  201. * obsolete GetInternalUnits function.
  202. */
  203. virtual int MilsToIuScalar() { return 1; }
  204. /* general Undo/Redo command control */
  205. /**
  206. * Function ClearUndoORRedoList (virtual).
  207. * this function must remove the aItemCount old commands from aList
  208. * and delete commands, pickers and picked items if needed
  209. * Because picked items must be deleted only if they are not in use, this
  210. * is a virtual pure function that must be created for SCH_SCREEN and
  211. * PCB_SCREEN
  212. * @param aList = the UNDO_REDO_CONTAINER of commands
  213. * @param aItemCount = number of old commands to delete. -1 to remove all
  214. * old commands this will empty the list of commands.
  215. * Commands are deleted from the older to the last.
  216. */
  217. virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) = 0;
  218. /**
  219. * Function ClearUndoRedoList
  220. * clear undo and redo list, using ClearUndoORRedoList()
  221. * picked items are deleted by ClearUndoORRedoList() according to their
  222. * status
  223. */
  224. virtual void ClearUndoRedoList();
  225. /**
  226. * Function PushCommandToUndoList
  227. * add a command to undo in undo list
  228. * delete the very old commands when the max count of undo commands is
  229. * reached
  230. * ( using ClearUndoORRedoList)
  231. */
  232. virtual void PushCommandToUndoList( PICKED_ITEMS_LIST* aItem );
  233. /**
  234. * Function PushCommandToRedoList
  235. * add a command to redo in redo list
  236. * delete the very old commands when the max count of redo commands is
  237. * reached
  238. * ( using ClearUndoORRedoList)
  239. */
  240. virtual void PushCommandToRedoList( PICKED_ITEMS_LIST* aItem );
  241. /** PopCommandFromUndoList
  242. * return the last command to undo and remove it from list
  243. * nothing is deleted.
  244. */
  245. virtual PICKED_ITEMS_LIST* PopCommandFromUndoList();
  246. /** PopCommandFromRedoList
  247. * return the last command to undo and remove it from list
  248. * nothing is deleted.
  249. */
  250. virtual PICKED_ITEMS_LIST* PopCommandFromRedoList();
  251. int GetUndoCommandCount() const
  252. {
  253. return m_UndoList.m_CommandsList.size();
  254. }
  255. int GetRedoCommandCount() const
  256. {
  257. return m_RedoList.m_CommandsList.size();
  258. }
  259. int GetMaxUndoItems() const { return m_UndoRedoCountMax; }
  260. void SetMaxUndoItems( int aMax )
  261. {
  262. if( aMax >= 0 && aMax < ABS_MAX_UNDO_ITEMS )
  263. m_UndoRedoCountMax = aMax;
  264. else
  265. {
  266. wxFAIL_MSG( "Maximum undo items not within limits" );
  267. m_UndoRedoCountMax = DEFAULT_MAX_UNDO_ITEMS;
  268. }
  269. }
  270. void SetModify() { m_FlagModified = true; }
  271. void ClrModify() { m_FlagModified = false; }
  272. void SetSave() { m_FlagSave = true; }
  273. void ClrSave() { m_FlagSave = false; }
  274. bool IsModify() const { return m_FlagModified; }
  275. bool IsSave() const { return m_FlagSave; }
  276. //----<zoom stuff>---------------------------------------------------------
  277. /**
  278. * Function GetZoom
  279. * returns the current "zoom factor", which is a measure of
  280. * "internal units per device unit", or "world units per device unit".
  281. * A device unit is typically a pixel.
  282. */
  283. double GetZoom() const { return m_Zoom; }
  284. /**
  285. * Function SetZoom
  286. * adjusts the current zoom factor.
  287. *
  288. * @param iu_per_du is the number of internal units (world units) per
  289. * device units (pixels typically).
  290. */
  291. bool SetZoom( double iu_per_du );
  292. bool SetNextZoom();
  293. bool SetPreviousZoom();
  294. bool SetFirstZoom();
  295. bool SetLastZoom();
  296. /**
  297. * Function GetMaxAllowedZoom
  298. * returns the maximum allowed zoom factor, which was established as the last entry
  299. * in m_ZoomList.
  300. */
  301. double GetMaxAllowedZoom() const { return m_ZoomList.size() ? *m_ZoomList.rbegin() : 1.0; }
  302. /**
  303. * Function GetMinAllowedZoom
  304. * returns the minimum allowed zoom factor, which was established as the first entry
  305. * in m_ZoomList.
  306. */
  307. double GetMinAllowedZoom() const { return m_ZoomList.size() ? *m_ZoomList.begin() : 1.0; }
  308. /**
  309. * Function SetScalingFactor
  310. * sets the scaling factor of "internal unit per device unit".
  311. * If the output device is a screen, then "device units" are pixels. The
  312. * "logical unit" is wx terminology, and corresponds to KiCad's "Internal Unit (IU)".
  313. * <p>
  314. * This scaling factor is "internal units per device unit". This function is
  315. * the same thing currently as SetZoom(), but clamps the argument within a
  316. * legal range.
  317. * @param iu_per_du is the current scale used to draw items onto the device
  318. * context wxDC.
  319. */
  320. void SetScalingFactor( double iu_per_du );
  321. /**
  322. * Function GetScalingFactor
  323. * returns the inverse of the current scale used to draw items on screen.
  324. * <p>
  325. * This function somehow got designed to be the inverse of SetScalingFactor().
  326. * <p>
  327. * device coordinates = user coordinates * GetScalingFactor()
  328. */
  329. double GetScalingFactor() const;
  330. //----<grid stuff>----------------------------------------------------------
  331. /**
  332. * Return the command ID of the currently selected grid.
  333. *
  334. * @return int - Currently selected grid command ID.
  335. */
  336. int GetGridCmdId() const { return m_Grid.m_CmdId; }
  337. /**
  338. * Return the grid size of the currently selected grid.
  339. *
  340. * @return wxRealPoint - The currently selected grid size.
  341. */
  342. const wxRealPoint& GetGridSize() const { return m_Grid.m_Size; }
  343. /**
  344. * Return the grid object of the currently selected grid.
  345. *
  346. * @return GRID_TYPE - The currently selected grid.
  347. */
  348. const GRID_TYPE& GetGrid() const { return m_Grid; }
  349. /**
  350. * set the current grid size m_Grid.
  351. * The size must be existing in grid list (in m_grids)
  352. * If not, the near existing grid size is used
  353. * @param size = the size of the new grid
  354. * @return the grid id offset (id from ID_POPUP_GRID_LEVEL_1000 )
  355. * of the currently selected grid.
  356. */
  357. int SetGrid( const wxRealPoint& size );
  358. /**
  359. * Function SetGrid
  360. * sets the grid size from command ID (not an index in grid list, but a wxID).
  361. * @param aCommandId = the wxWidgets command ID
  362. * @return the grid id offset (id from ID_POPUP_GRID_LEVEL_1000 )
  363. * of the currently selected grid.
  364. */
  365. int SetGrid( int aCommandId );
  366. void SetGridList( GRIDS& sizelist );
  367. void AddGrid( const GRID_TYPE& grid );
  368. void AddGrid( const wxRealPoint& size, int id );
  369. void AddGrid( const wxRealPoint& size, EDA_UNITS_T aUnit, int id );
  370. /**
  371. * Function GridExists
  372. * tests for grid command ID (not an index in grid list, but a wxID) exists in grid list.
  373. * @param aCommandId = the wxWidgets command ID
  374. * @return true if the grid exists in grid list.
  375. */
  376. bool GridExists( int aCommandId );
  377. /**
  378. * Function GetGridCount().
  379. * Return the size of the grid list.
  380. *
  381. * @returns - The size of the grid list.
  382. */
  383. size_t GetGridCount() const { return m_grids.size(); }
  384. /**
  385. * Function GetGrid()
  386. * Returns the grid object at \a aIndex.
  387. *
  388. * @param aIndex - The grid list index.
  389. * @return - The grid object at \a aIndex or the current grid if the grid list is empty.
  390. */
  391. GRID_TYPE& GetGrid( size_t aIndex );
  392. /**
  393. * Function GetGrids().
  394. * Returns the current list of grids.
  395. */
  396. const GRIDS& GetGrids() const
  397. {
  398. return m_grids;
  399. }
  400. /**
  401. * Function BuildGridsChoiceList().
  402. * Build the human readable list of grid list, for menus or combo boxes
  403. * the list shows the grid size both in mils or mm.
  404. * @param aGridsList = a wxArrayString to populate
  405. * @param aMmFirst = true to have mm first and mils after
  406. * false to have mils first and mm after
  407. * @return the index of the curr grid in list, if found or -1
  408. */
  409. int BuildGridsChoiceList( wxArrayString& aGridsList, bool aMmFirst) const;
  410. /**
  411. * Function GetClass
  412. * returns the class name.
  413. * @return wxString
  414. */
  415. virtual wxString GetClass() const
  416. {
  417. return wxT( "BASE_SCREEN" );
  418. }
  419. inline bool IsBlockActive() const { return !m_BlockLocate.IsIdle(); }
  420. void ClearBlockCommand() { m_BlockLocate.Clear(); }
  421. #if defined(DEBUG)
  422. void Show( int nestLevel, std::ostream& os ) const; // overload
  423. #endif
  424. };
  425. #endif // CLASS_BASE_SCREEN_H_