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.

542 lines
17 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-2021 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 <eda_text.h>
  27. #include <sch_item.h>
  28. #include <sch_field.h>
  29. #include <sch_connection.h> // for CONNECTION_TYPE
  30. class NETLIST_OBJECT_LIST;
  31. class HTML_MESSAGE_BOX;
  32. /*
  33. * Spin style for text items of all kinds on schematics
  34. * Basically a higher level abstraction of rotation and justification of text
  35. */
  36. class LABEL_SPIN_STYLE
  37. {
  38. public:
  39. enum SPIN : int
  40. {
  41. LEFT = 0,
  42. UP = 1,
  43. RIGHT = 2,
  44. BOTTOM = 3
  45. };
  46. LABEL_SPIN_STYLE() = default;
  47. constexpr LABEL_SPIN_STYLE( SPIN aSpin ) : m_spin( aSpin )
  48. {
  49. }
  50. constexpr bool operator==( SPIN a ) const
  51. {
  52. return m_spin == a;
  53. }
  54. constexpr bool operator!=( SPIN a ) const
  55. {
  56. return m_spin != a;
  57. }
  58. operator int() const
  59. {
  60. return static_cast<int>( m_spin );
  61. }
  62. LABEL_SPIN_STYLE RotateCW()
  63. {
  64. SPIN newSpin = m_spin;
  65. switch( m_spin )
  66. {
  67. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::UP; break;
  68. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  69. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  70. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  71. default: wxLogWarning( "RotateCCW encountered unknown current spin style" ); break;
  72. }
  73. return LABEL_SPIN_STYLE( newSpin );
  74. }
  75. LABEL_SPIN_STYLE RotateCCW()
  76. {
  77. SPIN newSpin = m_spin;
  78. switch( m_spin )
  79. {
  80. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  81. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  82. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::UP; break;
  83. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  84. default: wxLogWarning( "RotateCCW encountered unknown current spin style" ); break;
  85. }
  86. return LABEL_SPIN_STYLE( newSpin );
  87. }
  88. /*
  89. * Mirrors the label spin style across the X axis or simply swaps up and bottom
  90. */
  91. LABEL_SPIN_STYLE MirrorX()
  92. {
  93. SPIN newSpin = m_spin;
  94. switch( m_spin )
  95. {
  96. case LABEL_SPIN_STYLE::UP: newSpin = LABEL_SPIN_STYLE::BOTTOM; break;
  97. case LABEL_SPIN_STYLE::BOTTOM: newSpin = LABEL_SPIN_STYLE::UP; break;
  98. case LABEL_SPIN_STYLE::LEFT: break;
  99. case LABEL_SPIN_STYLE::RIGHT: break;
  100. default: wxLogWarning( "MirrorVertically encountered unknown current spin style" ); break;
  101. }
  102. return LABEL_SPIN_STYLE( newSpin );
  103. }
  104. /*
  105. * Mirrors the label spin style across the Y axis or simply swaps left and right
  106. */
  107. LABEL_SPIN_STYLE MirrorY()
  108. {
  109. SPIN newSpin = m_spin;
  110. switch( m_spin )
  111. {
  112. case LABEL_SPIN_STYLE::LEFT: newSpin = LABEL_SPIN_STYLE::RIGHT; break;
  113. case LABEL_SPIN_STYLE::RIGHT: newSpin = LABEL_SPIN_STYLE::LEFT; break;
  114. case LABEL_SPIN_STYLE::UP: break;
  115. case LABEL_SPIN_STYLE::BOTTOM: break;
  116. default: wxLogWarning( "MirrorHorizontally encountered unknown current spin style" ); break;
  117. }
  118. return LABEL_SPIN_STYLE( newSpin );
  119. }
  120. private:
  121. SPIN m_spin;
  122. };
  123. /*
  124. * Shape/Type of #SCH_HIERLABEL and #SCH_GLOBALLABEL.
  125. */
  126. enum class PINSHEETLABEL_SHAPE
  127. {
  128. PS_INPUT, // use "PS_INPUT" instead of "INPUT" to avoid colliding
  129. // with a Windows header on msys2
  130. PS_OUTPUT,
  131. PS_BIDI,
  132. PS_TRISTATE,
  133. PS_UNSPECIFIED
  134. };
  135. extern const char* SheetLabelType[]; /* names of types of labels */
  136. class SCH_TEXT : public SCH_ITEM, public EDA_TEXT
  137. {
  138. public:
  139. SCH_TEXT( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString,
  140. KICAD_T aType = SCH_TEXT_T );
  141. /**
  142. * Clones \a aText into a new object. All members are copied as is except
  143. * for the #m_isDangling member which is set to false. This prevents newly
  144. * copied objects derived from #SCH_TEXT from having their connection state
  145. * improperly set.
  146. */
  147. SCH_TEXT( const SCH_TEXT& aText );
  148. ~SCH_TEXT() { }
  149. static inline bool ClassOf( const EDA_ITEM* aItem )
  150. {
  151. return aItem && SCH_TEXT_T == aItem->Type();
  152. }
  153. virtual wxString GetClass() const override
  154. {
  155. return wxT( "SCH_TEXT" );
  156. }
  157. /**
  158. * Returns the set of contextual text variable tokens for this text item.
  159. *
  160. * @param[out] aVars
  161. */
  162. void GetContextualTextVars( wxArrayString* aVars ) const;
  163. wxString GetShownText( int aDepth = 0 ) const override;
  164. /**
  165. * Increment the label text, if it ends with a number.
  166. *
  167. * @param aIncrement = the increment value to add to the number ending the text.
  168. */
  169. bool IncrementLabel( int aIncrement );
  170. /**
  171. * Set a spin or rotation angle, along with specific horizontal and vertical justification
  172. * styles with each angle.
  173. *
  174. * @param aSpinStyle Spin style as per #LABEL_SPIN_STYLE storage class, may be the enum
  175. * values or int value
  176. */
  177. virtual void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle );
  178. LABEL_SPIN_STYLE GetLabelSpinStyle() const { return m_spin_style; }
  179. PINSHEETLABEL_SHAPE GetShape() const { return m_shape; }
  180. void SetShape( PINSHEETLABEL_SHAPE aShape ) { m_shape = aShape; }
  181. /**
  182. * This offset depends on the orientation, the type of text, and the area required to
  183. * draw the associated graphic symbol or to put the text above a wire.
  184. *
  185. * @return the offset between the SCH_TEXT position and the text itself position
  186. */
  187. virtual wxPoint GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const;
  188. void Print( const RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  189. /**
  190. * Calculate the graphic shape (a polygon) associated to the text.
  191. *
  192. * @param aPoints A buffer to fill with polygon corners coordinates
  193. * @param Pos Position of the shape, for texts and labels: do nothing
  194. */
  195. virtual void CreateGraphicShape( const RENDER_SETTINGS* aSettings,
  196. std::vector<wxPoint>& aPoints, const wxPoint& Pos ) const
  197. {
  198. aPoints.clear();
  199. }
  200. void SwapData( SCH_ITEM* aItem ) override;
  201. const EDA_RECT GetBoundingBox() const override;
  202. bool operator<( const SCH_ITEM& aItem ) const override;
  203. int GetTextOffset( const RENDER_SETTINGS* aSettings = nullptr ) const;
  204. int GetPenWidth() const override;
  205. // Geometric transforms (used in block operations):
  206. void Move( const wxPoint& aMoveVector ) override
  207. {
  208. EDA_TEXT::Offset( aMoveVector );
  209. }
  210. void MirrorHorizontally( int aCenter ) override;
  211. void MirrorVertically( int aCenter ) override;
  212. void Rotate( wxPoint aCenter ) override;
  213. virtual void Rotate90( bool aClockwise );
  214. virtual void MirrorSpinStyle( bool aLeftRight );
  215. bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
  216. {
  217. return SCH_ITEM::Matches( GetText(), aSearchData );
  218. }
  219. bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override
  220. {
  221. return EDA_TEXT::Replace( aSearchData );
  222. }
  223. virtual bool IsReplaceable() const override { return true; }
  224. void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
  225. bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
  226. const SCH_SHEET_PATH* aPath = nullptr ) override;
  227. bool IsDangling() const override { return m_isDangling; }
  228. void SetIsDangling( bool aIsDangling ) { m_isDangling = aIsDangling; }
  229. std::vector<wxPoint> GetConnectionPoints() const override;
  230. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  231. BITMAPS GetMenuImage() const override;
  232. wxPoint GetPosition() const override { return EDA_TEXT::GetTextPos(); }
  233. void SetPosition( const wxPoint& aPosition ) override { EDA_TEXT::SetTextPos( aPosition ); }
  234. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  235. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  236. void Plot( PLOTTER* aPlotter ) const override;
  237. EDA_ITEM* Clone() const override;
  238. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  239. #if defined(DEBUG)
  240. void Show( int nestLevel, std::ostream& os ) const override;
  241. #endif
  242. static HTML_MESSAGE_BOX* ShowSyntaxHelp( wxWindow* aParentWindow );
  243. protected:
  244. PINSHEETLABEL_SHAPE m_shape;
  245. /// True if not connected to another object if the object derive from SCH_TEXT
  246. /// supports connections.
  247. bool m_isDangling;
  248. CONNECTION_TYPE m_connectionType;
  249. /**
  250. * The orientation of text and any associated drawing elements of derived objects.
  251. * - 0 is the horizontal and left justified.
  252. * - 1 is vertical and top justified.
  253. * - 2 is horizontal and right justified. It is the equivalent of the mirrored 0 orientation.
  254. * - 3 is vertical and bottom justified. It is the equivalent of the mirrored 1 orientation.
  255. *
  256. * This is a duplication of m_Orient, m_HJustified, and m_VJustified in #EDA_TEXT but is
  257. * easier to handle than 3 parameters when editing and reading and saving files.
  258. */
  259. LABEL_SPIN_STYLE m_spin_style;
  260. };
  261. class SCH_LABEL : public SCH_TEXT
  262. {
  263. public:
  264. SCH_LABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString );
  265. // Do not create a copy constructor. The one generated by the compiler is adequate.
  266. ~SCH_LABEL() { }
  267. static inline bool ClassOf( const EDA_ITEM* aItem )
  268. {
  269. return aItem && SCH_LABEL_T == aItem->Type();
  270. }
  271. wxString GetClass() const override
  272. {
  273. return wxT( "SCH_LABEL" );
  274. }
  275. bool IsType( const KICAD_T aScanTypes[] ) const override;
  276. const EDA_RECT GetBoundingBox() const override;
  277. bool IsConnectable() const override { return true; }
  278. bool CanConnect( const SCH_ITEM* aItem ) const override
  279. {
  280. return aItem->Type() == SCH_LINE_T &&
  281. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  282. }
  283. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  284. BITMAPS GetMenuImage() const override;
  285. bool IsReplaceable() const override { return true; }
  286. EDA_ITEM* Clone() const override;
  287. bool IsPointClickableAnchor( const wxPoint& aPos ) const override
  288. {
  289. return m_isDangling && GetPosition() == aPos;
  290. }
  291. private:
  292. bool doIsConnected( const wxPoint& aPosition ) const override
  293. {
  294. return EDA_TEXT::GetTextPos() == aPosition;
  295. }
  296. };
  297. class SCH_GLOBALLABEL : public SCH_TEXT
  298. {
  299. public:
  300. SCH_GLOBALLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString );
  301. SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel );
  302. ~SCH_GLOBALLABEL() { }
  303. static inline bool ClassOf( const EDA_ITEM* aItem )
  304. {
  305. return aItem && SCH_GLOBAL_LABEL_T == aItem->Type();
  306. }
  307. wxString GetClass() const override
  308. {
  309. return wxT( "SCH_GLOBALLABEL" );
  310. }
  311. EDA_ITEM* Clone() const override;
  312. void SwapData( SCH_ITEM* aItem ) override;
  313. SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
  314. void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) override;
  315. void Rotate( wxPoint aCenter ) override;
  316. void Rotate90( bool aClockwise ) override;
  317. void MirrorSpinStyle( bool aLeftRight ) override;
  318. void MirrorHorizontally( int aCenter ) override;
  319. void MirrorVertically( int aCenter ) override;
  320. void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override;
  321. wxPoint GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const override;
  322. /**
  323. * Return the bounding box on the global label only, without taking in account
  324. * the intersheet references.
  325. */
  326. const EDA_RECT GetBoundingBoxBase() const;
  327. /**
  328. * Return the bounding box on the global label only, including the intersheet references.
  329. */
  330. const EDA_RECT GetBoundingBox() const override;
  331. void CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings,
  332. std::vector<wxPoint>& aPoints, const wxPoint& aPos ) const override;
  333. void UpdateIntersheetRefProps();
  334. void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
  335. bool ResolveTextVar( wxString* token, int aDepth ) const;
  336. bool IsConnectable() const override { return true; }
  337. bool CanConnect( const SCH_ITEM* aItem ) const override
  338. {
  339. return aItem->Type() == SCH_LINE_T &&
  340. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  341. }
  342. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  343. BITMAPS GetMenuImage() const override;
  344. void Print( const RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  345. void Plot( PLOTTER* aPlotter ) const override;
  346. SCH_FIELD* GetIntersheetRefs() { return &m_intersheetRefsField; }
  347. void SetIntersheetRefs( const SCH_FIELD& aField ) { m_intersheetRefsField = aField; }
  348. bool IsPointClickableAnchor( const wxPoint& aPos ) const override
  349. {
  350. return m_isDangling && GetPosition() == aPos;
  351. }
  352. void Move( const wxPoint& aMoveVector ) override
  353. {
  354. SCH_TEXT::Move( aMoveVector );
  355. m_intersheetRefsField.Move( aMoveVector );
  356. }
  357. private:
  358. bool doIsConnected( const wxPoint& aPosition ) const override
  359. {
  360. return EDA_TEXT::GetTextPos() == aPosition;
  361. }
  362. SCH_FIELD m_intersheetRefsField;
  363. };
  364. class SCH_HIERLABEL : public SCH_TEXT
  365. {
  366. public:
  367. SCH_HIERLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString,
  368. KICAD_T aType = SCH_HIER_LABEL_T );
  369. // Do not create a copy constructor. The one generated by the compiler is adequate.
  370. ~SCH_HIERLABEL() { }
  371. void Print( const RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
  372. static inline bool ClassOf( const EDA_ITEM* aItem )
  373. {
  374. return aItem && SCH_HIER_LABEL_T == aItem->Type();
  375. }
  376. wxString GetClass() const override
  377. {
  378. return wxT( "SCH_HIERLABEL" );
  379. }
  380. void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override;
  381. wxPoint GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const override;
  382. void CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<wxPoint>& aPoints,
  383. const wxPoint& aPos ) const override;
  384. void CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<wxPoint>& aPoints,
  385. const wxPoint& aPos, PINSHEETLABEL_SHAPE aShape ) const;
  386. const EDA_RECT GetBoundingBox() const override;
  387. bool IsConnectable() const override { return true; }
  388. bool CanConnect( const SCH_ITEM* aItem ) const override
  389. {
  390. return aItem->Type() == SCH_LINE_T &&
  391. ( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
  392. }
  393. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  394. BITMAPS GetMenuImage() const override;
  395. EDA_ITEM* Clone() const override;
  396. bool IsPointClickableAnchor( const wxPoint& aPos ) const override
  397. {
  398. return m_isDangling && GetPosition() == aPos;
  399. }
  400. private:
  401. bool doIsConnected( const wxPoint& aPosition ) const override
  402. {
  403. return EDA_TEXT::GetTextPos() == aPosition;
  404. }
  405. };
  406. #endif /* CLASS_TEXT_LABEL_H */