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.

247 lines
6.4 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 wanoadoo.fr
  5. * Copyright (C) 1992-2022 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. /**
  25. * @file sch_no_connect.cpp
  26. * @brief Class SCH_NO_CONNECT implementation.
  27. */
  28. #include <sch_draw_panel.h>
  29. #include <plotters/plotter.h>
  30. #include <bitmaps.h>
  31. #include <schematic.h>
  32. #include <sch_no_connect.h>
  33. #include <settings/color_settings.h>
  34. #include <default_values.h> // For some default values
  35. #include <core/mirror.h>
  36. #include <trigo.h>
  37. #include <gr_basic.h>
  38. SCH_NO_CONNECT::SCH_NO_CONNECT( const VECTOR2I& pos ) :
  39. SCH_ITEM( nullptr, SCH_NO_CONNECT_T )
  40. {
  41. m_pos = pos;
  42. m_size = schIUScale.MilsToIU( DEFAULT_NOCONNECT_SIZE ); ///< No-connect symbol size.
  43. SetLayer( LAYER_NOCONNECT );
  44. }
  45. EDA_ITEM* SCH_NO_CONNECT::Clone() const
  46. {
  47. return new SCH_NO_CONNECT( *this );
  48. }
  49. void SCH_NO_CONNECT::SwapData( SCH_ITEM* aItem )
  50. {
  51. SCH_ITEM::SwapFlags( aItem );
  52. wxCHECK_RET( ( aItem != nullptr ) && ( aItem->Type() == SCH_NO_CONNECT_T ),
  53. wxT( "Cannot swap no connect data with invalid item." ) );
  54. SCH_NO_CONNECT* item = (SCH_NO_CONNECT*)aItem;
  55. std::swap( m_pos, item->m_pos );
  56. std::swap( m_size, item->m_size );
  57. }
  58. const BOX2I SCH_NO_CONNECT::GetBoundingBox() const
  59. {
  60. int delta = ( GetPenWidth() + GetSize() ) / 2;
  61. BOX2I bbox( m_pos );
  62. bbox.Inflate( delta );
  63. return bbox;
  64. }
  65. void SCH_NO_CONNECT::ViewGetLayers( int aLayers[], int& aCount ) const
  66. {
  67. aCount = 2;
  68. aLayers[0] = LAYER_NOCONNECT;
  69. aLayers[1] = LAYER_SELECTION_SHADOWS;
  70. }
  71. void SCH_NO_CONNECT::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
  72. {
  73. DANGLING_END_ITEM item( NO_CONNECT_END, this, m_pos );
  74. aItemList.push_back( item );
  75. }
  76. int SCH_NO_CONNECT::GetPenWidth() const
  77. {
  78. if( !Schematic() )
  79. return 1;
  80. return std::max( Schematic()->Settings().m_DefaultLineWidth, 1 );
  81. }
  82. void SCH_NO_CONNECT::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
  83. const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
  84. {
  85. wxDC* DC = aSettings->GetPrintDC();
  86. int half = GetSize() / 2;
  87. int penWidth = GetEffectivePenWidth( aSettings );
  88. int pX = m_pos.x + aOffset.x;
  89. int pY = m_pos.y + aOffset.y;
  90. COLOR4D color = aSettings->GetLayerColor( LAYER_NOCONNECT );
  91. GRLine( DC, pX - half, pY - half, pX + half, pY + half, penWidth, color );
  92. GRLine( DC, pX + half, pY - half, pX - half, pY + half, penWidth, color );
  93. }
  94. void SCH_NO_CONNECT::MirrorVertically( int aCenter )
  95. {
  96. MIRROR( m_pos.y, aCenter );
  97. }
  98. void SCH_NO_CONNECT::MirrorHorizontally( int aCenter )
  99. {
  100. MIRROR( m_pos.x, aCenter );
  101. }
  102. void SCH_NO_CONNECT::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
  103. {
  104. RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
  105. }
  106. bool SCH_NO_CONNECT::HasConnectivityChanges( const SCH_ITEM* aItem,
  107. const SCH_SHEET_PATH* aInstance ) const
  108. {
  109. // Do not compare to ourself.
  110. if( aItem == this )
  111. return false;
  112. const SCH_NO_CONNECT* noConnect = dynamic_cast<const SCH_NO_CONNECT*>( aItem );
  113. // Don't compare against a different SCH_ITEM.
  114. wxCHECK( noConnect, false );
  115. return GetPosition() != noConnect->GetPosition();
  116. }
  117. std::vector<VECTOR2I> SCH_NO_CONNECT::GetConnectionPoints() const
  118. {
  119. return { m_pos };
  120. }
  121. bool SCH_NO_CONNECT::doIsConnected( const VECTOR2I& aPosition ) const
  122. {
  123. return m_pos == aPosition;
  124. }
  125. bool SCH_NO_CONNECT::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
  126. {
  127. int delta = ( GetPenWidth() + GetSize() ) / 2 + aAccuracy;
  128. VECTOR2I dist = aPosition - m_pos;
  129. if( ( std::abs( dist.x ) <= delta ) && ( std::abs( dist.y ) <= delta ) )
  130. return true;
  131. return false;
  132. }
  133. bool SCH_NO_CONNECT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
  134. {
  135. BOX2I rect = aRect;
  136. rect.Inflate( aAccuracy );
  137. if( aContained )
  138. return rect.Contains( GetBoundingBox() );
  139. return rect.Intersects( GetBoundingBox() );
  140. }
  141. void SCH_NO_CONNECT::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
  142. int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
  143. {
  144. if( aBackground )
  145. return;
  146. int delta = GetSize() / 2;
  147. int pX = m_pos.x;
  148. int pY = m_pos.y;
  149. int penWidth = GetEffectivePenWidth( getRenderSettings( aPlotter ) );
  150. aPlotter->SetCurrentLineWidth( penWidth );
  151. aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_NOCONNECT ) );
  152. aPlotter->MoveTo( VECTOR2I( pX - delta, pY - delta ) );
  153. aPlotter->FinishTo( VECTOR2I( pX + delta, pY + delta ) );
  154. aPlotter->MoveTo( VECTOR2I( pX + delta, pY - delta ) );
  155. aPlotter->FinishTo( VECTOR2I( pX - delta, pY + delta ) );
  156. }
  157. BITMAPS SCH_NO_CONNECT::GetMenuImage() const
  158. {
  159. return BITMAPS::noconn;
  160. }
  161. bool SCH_NO_CONNECT::operator==( const SCH_ITEM& aOther ) const
  162. {
  163. if( aOther.Type() != Type() )
  164. return false;
  165. const SCH_NO_CONNECT* other = static_cast<const SCH_NO_CONNECT*>( &aOther );
  166. if( m_pos != other->m_pos )
  167. return false;
  168. return true;
  169. }
  170. double SCH_NO_CONNECT::Similarity( const SCH_ITEM& aOther ) const
  171. {
  172. if( m_Uuid == aOther.m_Uuid )
  173. return 1.0;
  174. if( aOther.Type() != Type() )
  175. return 0.0;
  176. const SCH_NO_CONNECT* other = static_cast<const SCH_NO_CONNECT*>( &aOther );
  177. if( m_pos != other->m_pos )
  178. return 0.0;
  179. return 1.0;
  180. }