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

  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-2023 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 SCH_LABEL_H
  25. #define SCH_LABEL_H
  26. #include <sch_text.h>
  27. #include <sch_item.h>
  28. #include <sch_field.h>
  29. #include <sch_connection.h> // for CONNECTION_TYPE
  30. class SCH_LABEL_BASE : public SCH_TEXT
  31. {
  32. public:
  33. SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType );
  34. SCH_LABEL_BASE( const SCH_LABEL_BASE& aLabel );
  35. SCH_LABEL_BASE& operator=( const SCH_LABEL_BASE& aLabel );
  36. // Abstract class
  37. virtual wxString GetClass() const override = 0;
  38. bool IsType( const std::vector<KICAD_T>& aScanTypes ) const override;
  39. void SwapData( SCH_ITEM* aItem ) override;
  40. bool CanConnect( const SCH_ITEM* aItem ) const override
  41. {
  42. switch( aItem->Type() )
  43. {
  44. case SCH_LINE_T:
  45. return aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS;
  46. case SCH_BUS_WIRE_ENTRY_T:
  47. return true;
  48. case SCH_SYMBOL_T:
  49. return true;
  50. case SCH_LABEL_T:
  51. case SCH_GLOBAL_LABEL_T:
  52. case SCH_HIER_LABEL_T:
  53. case SCH_DIRECTIVE_LABEL_T:
  54. case SCH_SHEET_PIN_T:
  55. return true;
  56. default:
  57. return false;
  58. }
  59. }
  60. LABEL_FLAG_SHAPE GetShape() const override { return m_shape; }
  61. void SetShape( LABEL_FLAG_SHAPE aShape ) override { m_shape = aShape; }
  62. COLOR4D GetLabelColor() const;
  63. void SetLastResolvedState( const SCH_ITEM* aItem ) override
  64. {
  65. const SCH_LABEL_BASE* aLabel = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
  66. if( aLabel )
  67. m_lastResolvedColor = aLabel->m_lastResolvedColor;
  68. }
  69. static const wxString GetDefaultFieldName( const wxString& aName, bool aUseDefaultName );
  70. virtual int GetMandatoryFieldCount() { return 0; }
  71. std::vector<SCH_FIELD>& GetFields() { return m_fields; }
  72. const std::vector<SCH_FIELD>& GetFields() const { return m_fields; }
  73. /**
  74. * Set multiple schematic fields.
  75. *
  76. * @param aFields are the fields to set in this symbol.
  77. */
  78. void SetFields( const std::vector<SCH_FIELD>& aFields )
  79. {
  80. m_fields = aFields; // vector copying, length is changed possibly
  81. }
  82. void AddFields( const std::vector<SCH_FIELD>& aFields )
  83. {
  84. m_fields.insert( m_fields.end(), aFields.begin(), aFields.end() );
  85. }
  86. void AddField( const SCH_FIELD& aField )
  87. {
  88. m_fields.push_back( aField );
  89. }
  90. /**
  91. * Increment the label text, if it ends with a number.
  92. *
  93. * @param aIncrement = the increment value to add to the number ending the text.
  94. */
  95. bool IncrementLabel( int aIncrement );
  96. void Move( const VECTOR2I& aMoveVector ) override;
  97. void Rotate( const VECTOR2I& aCenter ) override;
  98. void Rotate90( bool aClockwise ) override;
  99. void MirrorSpinStyle( bool aLeftRight ) override;
  100. void MirrorHorizontally( int aCenter ) override;
  101. void MirrorVertically( int aCenter ) override;
  102. void SetPosition( const VECTOR2I& aPosition ) override;
  103. void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
  104. /**
  105. * Builds an array of { pageNumber, pageName } pairs.
  106. * @param pages [out] Array of { pageNumber, pageName } pairs.
  107. */
  108. void GetIntersheetRefs( std::vector<std::pair<wxString, wxString>>* pages );
  109. /**
  110. * Return the list of system text vars & fields for this label.
  111. */
  112. void GetContextualTextVars( wxArrayString* aVars ) const;
  113. /**
  114. * Resolve any references to system tokens supported by the label.
  115. *
  116. * @param aDepth a counter to limit recursion and circular references.
  117. */
  118. virtual bool ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const;
  119. wxString GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
  120. int aDepth = 0 ) const override;
  121. wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override
  122. {
  123. return GetShownText( nullptr, aAllowExtraText, aDepth );
  124. }
  125. bool HasCachedDriverName() const override;
  126. const wxString& GetCachedDriverName() const override;
  127. void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) override;
  128. INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
  129. const std::vector<KICAD_T>& scanTypes ) override;
  130. bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
  131. bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) override;
  132. VECTOR2I GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const override;
  133. /**
  134. * Calculate the graphic shape (a polygon) associated to the text.
  135. *
  136. * @param aPoints A buffer to fill with polygon corners coordinates
  137. * @param Pos Position of the shape, for texts and labels: do nothing
  138. */
  139. virtual void CreateGraphicShape( const RENDER_SETTINGS* aSettings,
  140. std::vector<VECTOR2I>& aPoints, const VECTOR2I& Pos ) const
  141. {
  142. aPoints.clear();
  143. }
  144. int GetLabelBoxExpansion( const RENDER_SETTINGS* aSettings = nullptr ) const;
  145. /**
  146. * Return the bounding box of the label only, without taking in account its fields.
  147. */
  148. virtual const BOX2I GetBodyBoundingBox() const;
  149. /**
  150. * Return the bounding box of the label including its fields.
  151. */
  152. const BOX2I GetBoundingBox() const override;
  153. bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
  154. bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
  155. std::vector<VECTOR2I> GetConnectionPoints() const override;
  156. void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) override;
  157. bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
  158. const SCH_SHEET_PATH* aPath = nullptr ) override;
  159. bool IsDangling() const override { return m_isDangling; }
  160. void SetIsDangling( bool aIsDangling ) { m_isDangling = aIsDangling; }
  161. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  162. void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
  163. void Plot( PLOTTER* aPlotter, bool aBackground ) const override;
  164. void Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& offset ) override;
  165. /**
  166. * @brief autoRotateOnPlacement
  167. * @return Returns true if the label rotation will be automatically set on the placement
  168. */
  169. bool AutoRotateOnPlacement() const;
  170. /**
  171. * @brief setAutoRotateOnPlacement
  172. * @param autoRotate If set to true when the label is placed in the connection to a
  173. * pin/net the direction will be automatically set according to the positioning of the net/pin
  174. */
  175. void SetAutoRotateOnPlacement( bool autoRotate = true );
  176. /**
  177. * @brief AutoRotateOnPlacementSupported
  178. * @return true if the automated rotation of the label is supported after the placement
  179. * At the moment it is supported for global and hierarchial labels
  180. */
  181. virtual bool AutoRotateOnPlacementSupported() const = 0;
  182. protected:
  183. void cacheShownText() override;
  184. protected:
  185. std::vector<SCH_FIELD> m_fields;
  186. LABEL_FLAG_SHAPE m_shape;
  187. CONNECTION_TYPE m_connectionType;
  188. bool m_isDangling;
  189. bool m_autoRotateOnPlacement = false;
  190. mutable COLOR4D m_lastResolvedColor;
  191. wxString m_cached_driver_name;
  192. };
  193. class SCH_LABEL : public SCH_LABEL_BASE
  194. {
  195. public:
  196. SCH_LABEL( const VECTOR2I& aPos = VECTOR2I( 0, 0 ), const wxString& aText = wxEmptyString );
  197. // Do not create a copy constructor. The one generated by the compiler is adequate.
  198. ~SCH_LABEL() { }
  199. static inline bool ClassOf( const EDA_ITEM* aItem )
  200. {
  201. return aItem && SCH_LABEL_T == aItem->Type();
  202. }
  203. wxString GetClass() const override
  204. {
  205. return wxT( "SCH_LABEL" );
  206. }
  207. const BOX2I GetBodyBoundingBox() const override;
  208. bool IsConnectable() const override { return true; }
  209. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
  210. BITMAPS GetMenuImage() const override;
  211. bool IsReplaceable() const override { return true; }
  212. EDA_ITEM* Clone() const override
  213. {
  214. return new SCH_LABEL( *this );
  215. }
  216. bool IsPointClickableAnchor( const VECTOR2I& aPos ) const override
  217. {
  218. return m_isDangling && GetPosition() == aPos;
  219. }
  220. bool AutoRotateOnPlacementSupported() const override { return false; }
  221. private:
  222. bool doIsConnected( const VECTOR2I& aPosition ) const override
  223. {
  224. return EDA_TEXT::GetTextPos() == aPosition;
  225. }
  226. };
  227. class SCH_DIRECTIVE_LABEL : public SCH_LABEL_BASE
  228. {
  229. public:
  230. SCH_DIRECTIVE_LABEL( const VECTOR2I& aPos = VECTOR2I( 0, 0 ) );
  231. SCH_DIRECTIVE_LABEL( const SCH_DIRECTIVE_LABEL& aClassLabel );
  232. ~SCH_DIRECTIVE_LABEL() { }
  233. static inline bool ClassOf( const EDA_ITEM* aItem )
  234. {
  235. return aItem && SCH_DIRECTIVE_LABEL_T == aItem->Type();
  236. }
  237. wxString GetClass() const override
  238. {
  239. return wxT( "SCH_DIRECTIVE_LABEL" );
  240. }
  241. EDA_ITEM* Clone() const override
  242. {
  243. return new SCH_DIRECTIVE_LABEL( *this );
  244. }
  245. void SwapData( SCH_ITEM* aItem ) override;
  246. int GetPinLength() const { return m_pinLength; }
  247. void SetPinLength( int aLength ) { m_pinLength = aLength; }
  248. int GetPenWidth() const override;
  249. void CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
  250. const VECTOR2I& aPos ) const override;
  251. void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
  252. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
  253. bool IsConnectable() const override { return true; }
  254. bool AutoRotateOnPlacementSupported() const override { return false; }
  255. void MirrorSpinStyle( bool aLeftRight ) override;
  256. void MirrorHorizontally( int aCenter ) override;
  257. void MirrorVertically( int aCenter ) override;
  258. private:
  259. int m_pinLength;
  260. int m_symbolSize;
  261. };
  262. class SCH_GLOBALLABEL : public SCH_LABEL_BASE
  263. {
  264. public:
  265. SCH_GLOBALLABEL( const VECTOR2I& aPos = VECTOR2I( 0, 0 ), const wxString& aText = wxEmptyString );
  266. SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel );
  267. ~SCH_GLOBALLABEL() { }
  268. static inline bool ClassOf( const EDA_ITEM* aItem )
  269. {
  270. return aItem && SCH_GLOBAL_LABEL_T == aItem->Type();
  271. }
  272. wxString GetClass() const override
  273. {
  274. return wxT( "SCH_GLOBALLABEL" );
  275. }
  276. EDA_ITEM* Clone() const override
  277. {
  278. return new SCH_GLOBALLABEL( *this );
  279. }
  280. int GetMandatoryFieldCount() override { return 1; }
  281. void SetTextSpinStyle( TEXT_SPIN_STYLE aSpinStyle ) override;
  282. VECTOR2I GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const override;
  283. void CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
  284. const VECTOR2I& aPos ) const override;
  285. bool ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const override;
  286. bool IsConnectable() const override { return true; }
  287. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  288. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
  289. BITMAPS GetMenuImage() const override;
  290. bool IsPointClickableAnchor( const VECTOR2I& aPos ) const override
  291. {
  292. return m_isDangling && GetPosition() == aPos;
  293. }
  294. bool AutoRotateOnPlacementSupported() const override { return true; }
  295. private:
  296. bool doIsConnected( const VECTOR2I& aPosition ) const override
  297. {
  298. return EDA_TEXT::GetTextPos() == aPosition;
  299. }
  300. };
  301. class SCH_HIERLABEL : public SCH_LABEL_BASE
  302. {
  303. public:
  304. SCH_HIERLABEL( const VECTOR2I& aPos = VECTOR2I( 0, 0 ), const wxString& aText = wxEmptyString,
  305. KICAD_T aType = SCH_HIER_LABEL_T );
  306. // Do not create a copy constructor. The one generated by the compiler is adequate.
  307. ~SCH_HIERLABEL() { }
  308. static inline bool ClassOf( const EDA_ITEM* aItem )
  309. {
  310. return aItem && SCH_HIER_LABEL_T == aItem->Type();
  311. }
  312. wxString GetClass() const override
  313. {
  314. return wxT( "SCH_HIERLABEL" );
  315. }
  316. void SetTextSpinStyle( TEXT_SPIN_STYLE aSpinStyle ) override;
  317. VECTOR2I GetSchematicTextOffset( const RENDER_SETTINGS* aSettings ) const override;
  318. void CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
  319. const VECTOR2I& aPos ) const override;
  320. void CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
  321. const VECTOR2I& aPos, LABEL_FLAG_SHAPE aShape ) const;
  322. const BOX2I GetBodyBoundingBox() const override;
  323. bool IsConnectable() const override { return true; }
  324. wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
  325. BITMAPS GetMenuImage() const override;
  326. EDA_ITEM* Clone() const override
  327. {
  328. return new SCH_HIERLABEL( *this );
  329. }
  330. bool IsPointClickableAnchor( const VECTOR2I& aPos ) const override
  331. {
  332. return m_isDangling && GetPosition() == aPos;
  333. }
  334. bool AutoRotateOnPlacementSupported() const override { return true; }
  335. private:
  336. bool doIsConnected( const VECTOR2I& aPosition ) const override
  337. {
  338. return EDA_TEXT::GetTextPos() == aPosition;
  339. }
  340. };
  341. #endif /* SCH_LABEL_H */