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.

316 lines
8.0 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
17 years ago
17 years ago
18 years ago
18 years ago
18 years ago
18 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) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 1992-2019 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. #include <algorithm>
  25. #include <bitmaps.h>
  26. #include <general.h>
  27. #include <geometry/shape_line_chain.h>
  28. #include <gr_text.h>
  29. #include <kicad_string.h>
  30. #include <plotter.h>
  31. #include <sch_draw_panel.h>
  32. #include <sch_edit_frame.h>
  33. #include <sch_sheet.h>
  34. #include <sch_painter.h>
  35. #include <trigo.h>
  36. SCH_SHEET_PIN::SCH_SHEET_PIN( SCH_SHEET* parent, const wxPoint& pos, const wxString& text ) :
  37. SCH_HIERLABEL( pos, text, SCH_SHEET_PIN_T ),
  38. m_edge( SHEET_UNDEFINED_SIDE )
  39. {
  40. SetParent( parent );
  41. wxASSERT( parent );
  42. m_layer = LAYER_SHEETLABEL;
  43. SetTextPos( pos );
  44. if( parent->IsVerticalOrientation() )
  45. SetEdge( SHEET_TOP_SIDE );
  46. else
  47. SetEdge( SHEET_LEFT_SIDE );
  48. m_shape = PINSHEETLABEL_SHAPE::PS_INPUT;
  49. m_isDangling = true;
  50. m_number = 2;
  51. }
  52. EDA_ITEM* SCH_SHEET_PIN::Clone() const
  53. {
  54. return new SCH_SHEET_PIN( *this );
  55. }
  56. void SCH_SHEET_PIN::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
  57. {
  58. // The icon selection is handle by the virtual method CreateGraphicShape called by ::Print
  59. SCH_HIERLABEL::Print( aSettings, aOffset );
  60. }
  61. void SCH_SHEET_PIN::SwapData( SCH_ITEM* aItem )
  62. {
  63. wxCHECK_RET( aItem->Type() == SCH_SHEET_PIN_T,
  64. wxString::Format( wxT( "SCH_SHEET_PIN object cannot swap data with %s object." ),
  65. aItem->GetClass() ) );
  66. SCH_SHEET_PIN* pin = ( SCH_SHEET_PIN* ) aItem;
  67. SCH_TEXT::SwapData( (SCH_TEXT*) pin );
  68. int tmp = pin->GetNumber();
  69. pin->SetNumber( GetNumber() );
  70. SetNumber( tmp );
  71. SHEET_SIDE stmp = pin->GetEdge();
  72. pin->SetEdge( GetEdge() );
  73. SetEdge( stmp );
  74. }
  75. bool SCH_SHEET_PIN::operator==( const SCH_SHEET_PIN* aPin ) const
  76. {
  77. return aPin == this;
  78. }
  79. int SCH_SHEET_PIN::GetPenWidth() const
  80. {
  81. return 1;
  82. }
  83. void SCH_SHEET_PIN::SetNumber( int aNumber )
  84. {
  85. wxASSERT( aNumber >= 2 );
  86. m_number = aNumber;
  87. }
  88. void SCH_SHEET_PIN::SetEdge( SHEET_SIDE aEdge )
  89. {
  90. SCH_SHEET* Sheet = GetParent();
  91. // use SHEET_UNDEFINED_SIDE to adjust text orientation without changing edge
  92. switch( aEdge )
  93. {
  94. case SHEET_LEFT_SIDE:
  95. m_edge = aEdge;
  96. SetTextX( Sheet->m_pos.x );
  97. SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT ); // Orientation horiz inverse
  98. break;
  99. case SHEET_RIGHT_SIDE:
  100. m_edge = aEdge;
  101. SetTextX( Sheet->m_pos.x + Sheet->m_size.x );
  102. SetLabelSpinStyle( LABEL_SPIN_STYLE::LEFT ); // Orientation horiz normal
  103. break;
  104. case SHEET_TOP_SIDE:
  105. m_edge = aEdge;
  106. SetTextY( Sheet->m_pos.y );
  107. SetLabelSpinStyle( LABEL_SPIN_STYLE::BOTTOM ); // Orientation vert BOTTOM
  108. break;
  109. case SHEET_BOTTOM_SIDE:
  110. m_edge = aEdge;
  111. SetTextY( Sheet->m_pos.y + Sheet->m_size.y );
  112. SetLabelSpinStyle( LABEL_SPIN_STYLE::UP ); // Orientation vert UP
  113. break;
  114. default:
  115. break;
  116. }
  117. }
  118. enum SHEET_SIDE SCH_SHEET_PIN::GetEdge() const
  119. {
  120. return m_edge;
  121. }
  122. void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos )
  123. {
  124. SCH_SHEET* sheet = GetParent();
  125. if( sheet == NULL )
  126. return;
  127. int leftSide = sheet->m_pos.x;
  128. int rightSide = sheet->m_pos.x + sheet->m_size.x;
  129. int topSide = sheet->m_pos.y;
  130. int botSide = sheet->m_pos.y + sheet->m_size.y;
  131. SHAPE_LINE_CHAIN sheetEdge;
  132. sheetEdge.Append( leftSide, topSide );
  133. sheetEdge.Append( rightSide, topSide );
  134. sheetEdge.Append( rightSide, botSide );
  135. sheetEdge.Append( leftSide, botSide );
  136. sheetEdge.Append( leftSide, topSide );
  137. switch( sheetEdge.NearestSegment( Pos ) )
  138. {
  139. case 0: SetEdge( SHEET_TOP_SIDE ); break;
  140. case 1: SetEdge( SHEET_RIGHT_SIDE ); break;
  141. case 2: SetEdge( SHEET_BOTTOM_SIDE ); break;
  142. case 3: SetEdge( SHEET_LEFT_SIDE ); break;
  143. default: wxASSERT( "Invalid segment number" );
  144. }
  145. switch( GetEdge() )
  146. {
  147. case SHEET_RIGHT_SIDE:
  148. case SHEET_LEFT_SIDE:
  149. SetTextY( Pos.y );
  150. if( GetTextPos().y < topSide )
  151. SetTextY( topSide );
  152. if( GetTextPos().y > botSide )
  153. SetTextY( botSide );
  154. break;
  155. case SHEET_BOTTOM_SIDE:
  156. case SHEET_TOP_SIDE:
  157. SetTextX( Pos.x );
  158. if( GetTextPos().x < leftSide )
  159. SetTextX( leftSide );
  160. if( GetTextPos().x > rightSide )
  161. SetTextX( rightSide );
  162. break;
  163. case SHEET_UNDEFINED_SIDE:
  164. wxASSERT( "Undefined sheet side" );
  165. }
  166. }
  167. void SCH_SHEET_PIN::MirrorX( int aXaxis_position )
  168. {
  169. int p = GetTextPos().y - aXaxis_position;
  170. SetTextY( aXaxis_position - p );
  171. switch( m_edge )
  172. {
  173. case SHEET_TOP_SIDE: SetEdge( SHEET_BOTTOM_SIDE ); break;
  174. case SHEET_BOTTOM_SIDE: SetEdge( SHEET_TOP_SIDE ); break;
  175. default: break;
  176. }
  177. }
  178. void SCH_SHEET_PIN::MirrorY( int aYaxis_position )
  179. {
  180. int p = GetTextPos().x - aYaxis_position;
  181. SetTextX( aYaxis_position - p );
  182. switch( m_edge )
  183. {
  184. case SHEET_LEFT_SIDE: SetEdge( SHEET_RIGHT_SIDE ); break;
  185. case SHEET_RIGHT_SIDE: SetEdge( SHEET_LEFT_SIDE ); break;
  186. default: break;
  187. }
  188. }
  189. void SCH_SHEET_PIN::Rotate( wxPoint aPosition )
  190. {
  191. wxPoint pt = GetTextPos();
  192. RotatePoint( &pt, aPosition, 900 );
  193. ConstrainOnEdge( pt );
  194. }
  195. void SCH_SHEET_PIN::CreateGraphicShape( RENDER_SETTINGS* aRenderSettings,
  196. std::vector<wxPoint>& aPoints, const wxPoint& aPos )
  197. {
  198. /*
  199. * These are the same icon shapes as SCH_HIERLABEL but the graphic icon is slightly
  200. * different in 2 cases:
  201. * for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL
  202. * for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL
  203. */
  204. PINSHEETLABEL_SHAPE tmp = m_shape;
  205. switch( m_shape )
  206. {
  207. case PINSHEETLABEL_SHAPE::PS_INPUT: m_shape = PINSHEETLABEL_SHAPE::PS_OUTPUT; break;
  208. case PINSHEETLABEL_SHAPE::PS_OUTPUT: m_shape = PINSHEETLABEL_SHAPE::PS_INPUT; break;
  209. default: break;
  210. }
  211. SCH_HIERLABEL::CreateGraphicShape( aRenderSettings, aPoints, aPos );
  212. m_shape = tmp;
  213. }
  214. void SCH_SHEET_PIN::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
  215. {
  216. DANGLING_END_ITEM item( SHEET_LABEL_END, this, GetTextPos() );
  217. aItemList.push_back( item );
  218. }
  219. wxString SCH_SHEET_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const
  220. {
  221. return wxString::Format( _( "Hierarchical Sheet Pin %s" ), ShortenedShownText() );
  222. }
  223. BITMAP_DEF SCH_SHEET_PIN::GetMenuImage() const
  224. {
  225. return add_hierar_pin_xpm;
  226. }
  227. bool SCH_SHEET_PIN::HitTest( const wxPoint& aPoint, int aAccuracy ) const
  228. {
  229. EDA_RECT rect = GetBoundingBox();
  230. rect.Inflate( aAccuracy );
  231. return rect.Contains( aPoint );
  232. }
  233. #if defined(DEBUG)
  234. void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os ) const
  235. {
  236. // XML output:
  237. NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">"
  238. << " pin_name=\"" << TO_UTF8( GetText() )
  239. << '"' << "/>\n" << std::flush;
  240. }
  241. #endif