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.

473 lines
14 KiB

7 years ago
18 years ago
18 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, jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef CLASS_TEXT_LABEL_H
  25. #define CLASS_TEXT_LABEL_H
  26. #include <macros.h>
  27. #include <eda_text.h>
  28. #include <sch_item.h>
  29. #include <sch_connection.h> // for CONNECTION_TYPE
  30. class NETLIST_OBJECT_LIST;
  31. /*
  32. * Spin style for text items of all kinds on schematics
  33. * Basically a higher level abstraction of rotation and justification of text
  34. */
  35. class LABEL_SPIN_STYLE
  36. {
  37. public:
  38. enum SPIN : int
  39. {
  40. LEFT = 0,
  41. UP = 1,
  42. RIGHT = 2,
  43. BOTTOM = 3
  44. };
  45. LABEL_SPIN_STYLE() = default;
  46. constexpr LABEL_SPIN_STYLE( SPIN aSpin ) : m_spin( aSpin )
  47. {
  48. }
  49. constexpr bool operator==( SPIN a ) const
  50. {
  51. return m_spin == a;
  52. }
  53. constexpr bool operator!=( SPIN a ) const
  54. {
  55. return m_spin != a;
  56. }
  57. operator int() const
  58. {
  59. return static_cast<int>( m_spin );
  60. }
  61. LABEL_SPIN_STYLE RotateCW()
  62. {
  63. SPIN newSpin = m_spin;
  64. switch( m_spin )
  65. {
  66. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::UP; break;
  67. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  68. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  69. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  70. default: wxLogWarning( "RotateCCW encountered unknown current spin style" ); break;
  71. }
  72. return LABEL_SPIN_STYLE( newSpin );
  73. }
  74. LABEL_SPIN_STYLE RotateCCW()
  75. {
  76. SPIN newSpin = m_spin;
  77. switch( m_spin )
  78. {
  79. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  80. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  81. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::UP; break;
  82. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  83. default: wxLogWarning( "RotateCCW encountered unknown current spin style" ); break;
  84. }
  85. return LABEL_SPIN_STYLE( newSpin );
  86. }
  87. /*
  88. * Mirrors the label spin style across the X axis or simply swaps up and bottom
  89. */
  90. LABEL_SPIN_STYLE MirrorX()
  91. {
  92. SPIN newSpin = m_spin;
  93. switch( m_spin )
  94. {
  95. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  96. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::UP; break;
  97. case LABEL_SPIN_STYLE::LEFT: break;
  98. case LABEL_SPIN_STYLE::RIGHT: break;
  99. default: wxLogWarning( "MirrorX encountered unknown current spin style" ); break;
  100. }
  101. return LABEL_SPIN_STYLE( newSpin );
  102. }
  103. /*
  104. * Mirrors the label spin style across the Y axis or simply swaps left and right
  105. */
  106. LABEL_SPIN_STYLE MirrorY()
  107. {
  108. SPIN newSpin = m_spin;
  109. switch( m_spin )
  110. {
  111. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  112. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  113. case LABEL_SPIN_STYLE::UP: break;
  114. case LABEL_SPIN_STYLE::BOTTOM: break;
  115. default: wxLogWarning( "MirrorY encountered unknown current spin style" ); break;
  116. }
  117. return LABEL_SPIN_STYLE( newSpin );
  118. }
  119. private:
  120. SPIN m_spin;
  121. };
  122. /* Shape/Type of SCH_HIERLABEL and SCH_GLOBALLABEL
  123. * mainly used to handle the graphic associated shape
  124. */
  125. enum class PINSHEETLABEL_SHAPE
  126. {
  127. PS_INPUT, // use "PS_INPUT" instead of "INPUT" to avoid colliding
  128. // with a Windows header on msys2
  129. PS_OUTPUT,
  130. PS_BIDI,
  131. PS_TRISTATE,
  132. PS_UNSPECIFIED
  133. };
  134. extern const char* SheetLabelType[]; /* names of types of labels */
  135. class SCH_TEXT : public SCH_ITEM, public EDA_TEXT
  136. {
  137. protected:
  138. PINSHEETLABEL_SHAPE m_shape;
  139. /// True if not connected to another object if the object derive from SCH_TEXT
  140. /// supports connections.
  141. bool m_isDangling;
  142. CONNECTION_TYPE m_connectionType;
  143. /**
  144. * The orientation of text and any associated drawing elements of derived objects.
  145. * 0 is the horizontal and left justified.
  146. * 1 is vertical and top justified.
  147. * 2 is horizontal and right justified. It is the equivalent of the mirrored 0 orentation.
  148. * 3 is veritcal and bottom justifiend. It is the equivalent of the mirrored 1 orentation.
  149. * This is a duplicattion of m_Orient, m_HJustified, and m_VJustified in #EDA_TEXT but is
  150. * easier to handle than 3 parameters when editing and reading and saving files.
  151. */
  152. LABEL_SPIN_STYLE m_spin_style;
  153. public:
  154. SCH_TEXT( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString,
  155. KICAD_T aType = SCH_TEXT_T );
  156. /**
  157. * Clones \a aText into a new object. All members are copied as is except
  158. * for the #m_isDangling member which is set to false. This prevents newly
  159. * copied objects derived from #SCH_TEXT from having their connection state
  160. * improperly set.
  161. */
  162. SCH_TEXT( const SCH_TEXT& aText );
  163. ~SCH_TEXT() { }
  164. static inline bool ClassOf( const EDA_ITEM* aItem )
  165. {
  166. return aItem && SCH_TEXT_T == aItem->Type();
  167. }
  168. virtual wxString GetClass() const override
  169. {
  170. return wxT( "SCH_TEXT" );
  171. }
  172. /**
  173. * Returns the set of contextual text variable tokens for this text item.
  174. * @param aVars [out]
  175. */
  176. void GetContextualTextVars( wxArrayString* aVars ) const;
  177. wxString GetShownText( int aDepth = 0 ) const override;
  178. /**
  179. * Increment the label text, if it ends with a number.
  180. *
  181. * @param aIncrement = the increment value to add to the number ending the text.
  182. */
  183. void IncrementLabel( int aIncrement );
  184. /**
  185. * Set a spin or rotation angle, along with specific horizontal and vertical justification
  186. * styles with each angle.
  187. *
  188. * @param aSpinStyle Spin style as per LABEL_SPIN_STYLE storage class, may be the enum values or int value
  189. */
  190. virtual void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle );
  191. LABEL_SPIN_STYLE GetLabelSpinStyle() const
  192. {
  193. return m_spin_style;
  194. }
  195. PINSHEETLABEL_SHAPE GetShape() const { return m_shape; }
  196. void SetShape( PINSHEETLABEL_SHAPE aShape ) { m_shape = aShape; }
  197. /**
  198. * @return the offset between the SCH_TEXT position and the text itself position
  199. *
  200. * This offset depends on the orientation, the type of text, and the area required to
  201. * draw the associated graphic symbol or to put the text above a wire.
  202. */
  203. virtual wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const;
  204. void Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  205. /**
  206. * Calculate the graphic shape (a polygon) associated to the text.
  207. *
  208. * @param aPoints A buffer to fill with polygon corners coordinates
  209. * @param Pos Position of the shape, for texts and labels: do nothing
  210. * Mainly for derived classes (SCH_SHEET_PIN and Hierarchical labels)
  211. */
  212. virtual void CreateGraphicShape( RENDER_SETTINGS* aSettings,
  213. std::vector <wxPoint>& aPoints, const wxPoint& Pos )
  214. {
  215. aPoints.clear();
  216. }
  217. void SwapData( SCH_ITEM* aItem ) override;
  218. const EDA_RECT GetBoundingBox() const override;
  219. bool operator<( const SCH_ITEM& aItem ) const override;
  220. int GetTextOffset( RENDER_SETTINGS* aSettings ) const;
  221. int GetPenWidth() const override;
  222. // Geometric transforms (used in block operations):
  223. void Move( const wxPoint& aMoveVector ) override
  224. {
  225. EDA_TEXT::Offset( aMoveVector );
  226. }
  227. void MirrorY( int aYaxis_position ) override;
  228. void MirrorX( int aXaxis_position ) override;
  229. void Rotate( wxPoint aPosition ) override;
  230. bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override
  231. {
  232. return SCH_ITEM::Matches( GetText(), aSearchData );
  233. }
  234. bool Replace( wxFindReplaceData& aSearchData, void* aAuxData ) override
  235. {
  236. return EDA_TEXT::Replace( aSearchData );
  237. }
  238. virtual bool IsReplaceable() const override { return true; }
  239. void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
  240. bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
  241. const SCH_SHEET_PATH* aPath = nullptr ) override;
  242. bool IsDangling() const override { return m_isDangling; }
  243. void SetIsDangling( bool aIsDangling ) { m_isDangling = aIsDangling; }
  244. void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const override;
  245. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  246. BITMAP_DEF GetMenuImage() const override;
  247. wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
  248. void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); }
  249. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  250. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  251. void Plot( PLOTTER* aPlotter ) override;
  252. EDA_ITEM* Clone() const override;
  253. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  254. #if defined(DEBUG)
  255. void Show( int nestLevel, std::ostream& os ) const override;
  256. #endif
  257. static void ShowSyntaxHelp( wxWindow* aParentWindow );
  258. };
  259. class SCH_LABEL : public SCH_TEXT
  260. {
  261. public:
  262. SCH_LABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString );
  263. // Do not create a copy constructor. The one generated by the compiler is adequate.
  264. ~SCH_LABEL() { }
  265. static inline bool ClassOf( const EDA_ITEM* aItem )
  266. {
  267. return aItem && SCH_LABEL_T == aItem->Type();
  268. }
  269. wxString GetClass() const override
  270. {
  271. return wxT( "SCH_LABEL" );
  272. }
  273. bool IsType( const KICAD_T aScanTypes[] ) const override;
  274. const EDA_RECT GetBoundingBox() const override;
  275. bool IsConnectable() const override { return true; }
  276. bool CanConnect( const SCH_ITEM* aItem ) const override
  277. {
  278. return aItem->Type() == SCH_LINE_T &&
  279. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  280. }
  281. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  282. BITMAP_DEF GetMenuImage() const override;
  283. bool IsReplaceable() const override { return true; }
  284. EDA_ITEM* Clone() const override;
  285. private:
  286. bool doIsConnected( const wxPoint& aPosition ) const override { return EDA_TEXT::GetTextPos() == aPosition; }
  287. };
  288. class SCH_GLOBALLABEL : public SCH_TEXT
  289. {
  290. public:
  291. SCH_GLOBALLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString );
  292. // Do not create a copy constructor. The one generated by the compiler is adequate.
  293. ~SCH_GLOBALLABEL() { }
  294. void Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  295. static inline bool ClassOf( const EDA_ITEM* aItem )
  296. {
  297. return aItem && SCH_GLOBAL_LABEL_T == aItem->Type();
  298. }
  299. wxString GetClass() const override
  300. {
  301. return wxT( "SCH_GLOBALLABEL" );
  302. }
  303. void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override;
  304. wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override;
  305. const EDA_RECT GetBoundingBox() const override;
  306. void CreateGraphicShape( RENDER_SETTINGS* aRenderSettings,
  307. std::vector<wxPoint>& aPoints, const wxPoint& aPos ) override;
  308. bool IsConnectable() const override { return true; }
  309. bool CanConnect( const SCH_ITEM* aItem ) const override
  310. {
  311. return aItem->Type() == SCH_LINE_T &&
  312. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  313. }
  314. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  315. BITMAP_DEF GetMenuImage() const override;
  316. EDA_ITEM* Clone() const override;
  317. private:
  318. bool doIsConnected( const wxPoint& aPosition ) const override { return EDA_TEXT::GetTextPos() == aPosition; }
  319. };
  320. class SCH_HIERLABEL : public SCH_TEXT
  321. {
  322. public:
  323. SCH_HIERLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString,
  324. KICAD_T aType = SCH_HIER_LABEL_T );
  325. // Do not create a copy constructor. The one generated by the compiler is adequate.
  326. ~SCH_HIERLABEL() { }
  327. void Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  328. static inline bool ClassOf( const EDA_ITEM* aItem )
  329. {
  330. return aItem && SCH_HIER_LABEL_T == aItem->Type();
  331. }
  332. wxString GetClass() const override
  333. {
  334. return wxT( "SCH_HIERLABEL" );
  335. }
  336. void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override;
  337. wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override;
  338. void CreateGraphicShape( RENDER_SETTINGS* aSettings, std::vector<wxPoint>& aPoints,
  339. const wxPoint& Pos ) override;
  340. const EDA_RECT GetBoundingBox() const override;
  341. bool IsConnectable() const override { return true; }
  342. bool CanConnect( const SCH_ITEM* aItem ) const override
  343. {
  344. return aItem->Type() == SCH_LINE_T &&
  345. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  346. }
  347. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  348. BITMAP_DEF GetMenuImage() const override;
  349. EDA_ITEM* Clone() const override;
  350. private:
  351. bool doIsConnected( const wxPoint& aPosition ) const override { return EDA_TEXT::GetTextPos() == aPosition; }
  352. };
  353. #endif /* CLASS_TEXT_LABEL_H */