KiCad PCB EDA Suite
sch_line.cpp
Go to the documentation of this file.
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 
30 #include <fctsys.h>
31 #include <gr_basic.h>
32 #include <macros.h>
33 #include <sch_draw_panel.h>
34 #include <sch_painter.h>
35 #include <plotter.h>
36 #include <base_units.h>
37 #include <eeschema_config.h>
38 #include <general.h>
39 #include <sch_line.h>
40 #include <sch_edit_frame.h>
42 #include <netlist_object.h>
43 #include <sch_view.h>
44 #include <schematic.h>
45 
46 
47 static wxPenStyle getwxPenStyle( PLOT_DASH_TYPE aType )
48 {
49  switch( aType )
50  {
53  return wxPENSTYLE_SOLID;
55  return wxPENSTYLE_SHORT_DASH;
57  return wxPENSTYLE_DOT;
59  return wxPENSTYLE_DOT_DASH;
60  default:
61  wxFAIL_MSG( "Unhandled PlotDashType" );
62  return wxPENSTYLE_SOLID;
63  }
64 }
65 
66 
67 SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
69 {
70  m_start = pos;
71  m_end = pos;
73  m_size = 0;
75  m_color = COLOR4D::UNSPECIFIED;
76 
77  switch( layer )
78  {
79  default:
81  break;
82 
83  case LAYER_WIRE:
85  break;
86 
87  case LAYER_BUS:
89  break;
90  }
91 }
92 
93 
94 SCH_LINE::SCH_LINE( const SCH_LINE& aLine ) :
95  SCH_ITEM( aLine )
96 {
97  m_start = aLine.m_start;
98  m_end = aLine.m_end;
99  m_size = aLine.m_size;
100  m_style = aLine.m_style;
101  m_color = aLine.m_color;
104 }
105 
106 
108 {
109  return new SCH_LINE( *this );
110 }
111 
112 
113 /*
114  * Conversion between PLOT_DASH_TYPE values and style names displayed
115  */
116 const std::map<PLOT_DASH_TYPE, const char*> lineStyleNames{
117  { PLOT_DASH_TYPE::SOLID, "solid" },
118  { PLOT_DASH_TYPE::DASH, "dashed" },
119  { PLOT_DASH_TYPE::DASHDOT, "dash_dot" },
120  { PLOT_DASH_TYPE::DOT, "dotted" },
121 };
122 
123 
125 {
126  auto resultIt = lineStyleNames.find( aStyle );
127 
128  //legacy behavior is to default to dash if there is no name
129  return resultIt == lineStyleNames.end() ? lineStyleNames.find( PLOT_DASH_TYPE::DASH )->second :
130  resultIt->second;
131 }
132 
133 
134 PLOT_DASH_TYPE SCH_LINE::GetLineStyleByName( const wxString& aStyleName )
135 {
136  PLOT_DASH_TYPE id = PLOT_DASH_TYPE::DEFAULT; // Default style id
137 
138  //find the name by value
139  auto resultIt = std::find_if( lineStyleNames.begin(), lineStyleNames.end(),
140  [aStyleName]( const auto& it ) { return it.second == aStyleName; } );
141 
142  if( resultIt != lineStyleNames.end() )
143  id = resultIt->first;
144 
145  return id;
146 }
147 
148 
149 void SCH_LINE::Move( const wxPoint& aOffset )
150 {
151  if( aOffset != wxPoint( 0, 0 ) )
152  {
153  m_start += aOffset;
154  m_end += aOffset;
155  SetModified();
156  }
157 }
158 
159 
160 void SCH_LINE::MoveStart( const wxPoint& aOffset )
161 {
162  if( aOffset != wxPoint( 0, 0 ) )
163  {
164  m_start += aOffset;
165  SetModified();
166  }
167 }
168 
169 
170 void SCH_LINE::MoveEnd( const wxPoint& aOffset )
171 {
172  if( aOffset != wxPoint( 0, 0 ) )
173  {
174  m_end += aOffset;
175  SetModified();
176  }
177 }
178 
179 
180 #if defined(DEBUG)
181 
182 void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
183 {
184  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
185  << " layer=\"" << m_Layer << '"'
186  << " startIsDangling=\"" << m_startIsDangling
187  << '"' << " endIsDangling=\""
188  << m_endIsDangling << '"' << ">"
189  << " <start" << m_start << "/>"
190  << " <end" << m_end << "/>" << "</"
191  << GetClass().Lower().mb_str() << ">\n";
192 }
193 
194 #endif
195 
196 
197 void SCH_LINE::ViewGetLayers( int aLayers[], int& aCount ) const
198 {
199  aCount = 2;
200  aLayers[0] = m_Layer;
201  aLayers[1] = LAYER_SELECTION_SHADOWS;
202 }
203 
204 
206 {
207  int width = m_size / 2;
208  int extra = m_size & 0x1;
209 
210  int xmin = std::min( m_start.x, m_end.x ) - width;
211  int ymin = std::min( m_start.y, m_end.y ) - width;
212 
213  int xmax = std::max( m_start.x, m_end.x ) + width + extra;
214  int ymax = std::max( m_start.y, m_end.y ) + width + extra;
215 
216  EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin, ymax - ymin ) );
217 
218  return ret;
219 }
220 
221 
222 double SCH_LINE::GetLength() const
223 {
224  return GetLineLength( m_start, m_end );
225 }
226 
227 
228 void SCH_LINE::SetLineColor( const COLOR4D aColor )
229 {
230  m_color = aColor;
231 }
232 
233 
234 void SCH_LINE::SetLineColor( const double r, const double g, const double b, const double a )
235 {
236  COLOR4D newColor(r, g, b, a);
237 
238  if( newColor == COLOR4D::UNSPECIFIED )
239  m_color = COLOR4D::UNSPECIFIED;
240  else
241  {
242  // Eeschema does not allow alpha channel in colors
243  newColor.a = 1.0;
244  m_color = newColor;
245  }
246 }
247 
248 
250 {
251  return m_color;
252 }
253 
254 
256 {
257  if( IsGraphicLine() )
258  return PLOT_DASH_TYPE::DASH;
259 
260  return PLOT_DASH_TYPE::SOLID;
261 }
262 
263 
264 void SCH_LINE::SetLineStyle( const int aStyleId )
265 {
266  SetLineStyle( static_cast<PLOT_DASH_TYPE>( aStyleId ) );
267 }
268 
269 
271 {
272  if( aStyle == GetDefaultStyle() )
274  else
275  m_style = aStyle;
276 }
277 
278 
280 {
282  return m_style;
283 
284  return GetDefaultStyle();
285 }
286 
287 
288 void SCH_LINE::SetLineWidth( const int aSize )
289 {
290  m_size = aSize;
291 }
292 
293 
295 {
296  if( m_size == 0 && Schematic() )
297  return std::max( Schematic()->Settings().m_DefaultLineWidth, 1 );
298 
299  return std::max( m_size, 1 );
300 }
301 
302 
303 void SCH_LINE::Print( RENDER_SETTINGS* aSettings, const wxPoint& offset )
304 {
305  wxDC* DC = aSettings->GetPrintDC();
307  wxPoint start = m_start;
308  wxPoint end = m_end;
309  int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
310 
311  if( color == COLOR4D::UNSPECIFIED )
312  color = aSettings->GetLayerColor( m_Layer );
313 
314  GRLine( nullptr, DC, start.x, start.y, end.x, end.y, penWidth, color,
316 }
317 
318 
319 void SCH_LINE::MirrorX( int aXaxis_position )
320 {
321  MIRROR( m_start.y, aXaxis_position );
322  MIRROR( m_end.y, aXaxis_position );
323 }
324 
325 
326 void SCH_LINE::MirrorY( int aYaxis_position )
327 {
328  MIRROR( m_start.x, aYaxis_position );
329  MIRROR( m_end.x, aYaxis_position );
330 }
331 
332 
333 void SCH_LINE::Rotate( wxPoint aPosition )
334 {
335  RotatePoint( &m_start, aPosition, 900 );
336  RotatePoint( &m_end, aPosition, 900 );
337 }
338 
339 
341 {
342  RotatePoint( &m_start, aPosition, 900 );
343 }
344 
345 
346 void SCH_LINE::RotateEnd( wxPoint aPosition )
347 {
348  RotatePoint( &m_end, aPosition, 900 );
349 }
350 
351 
352 bool SCH_LINE::IsSameQuadrant( SCH_LINE* aLine, const wxPoint& aPosition )
353 {
354  wxPoint first;
355  wxPoint second;
356 
357  if( m_start == aPosition )
358  first = m_end - aPosition;
359  else if( m_end == aPosition )
360  first = m_start - aPosition;
361  else
362  return false;
363 
364  if( aLine->m_start == aPosition )
365  second = aLine->m_end - aPosition;
366  else if( aLine->m_end == aPosition )
367  second = aLine->m_start - aPosition;
368  else
369  return false;
370 
371  return ( sign( first.x ) == sign( second.x ) && sign( first.y ) == sign( second.y ) );
372 }
373 
374 
376 {
377  wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
378  wxT( "Cannot test line segment for overlap." ) );
379 
380  wxPoint firstSeg = m_end - m_start;
381  wxPoint secondSeg = aLine->m_end - aLine->m_start;
382 
383  // Use long long here to avoid overflow in calculations
384  return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
385 }
386 
387 
389 {
390  auto less = []( const wxPoint& lhs, const wxPoint& rhs ) -> bool
391  {
392  if( lhs.x == rhs.x )
393  return lhs.y < rhs.y;
394  return lhs.x < rhs.x;
395  };
396 
397  wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, NULL,
398  wxT( "Cannot test line segment for overlap." ) );
399 
400  if( this == aLine || GetLayer() != aLine->GetLayer() )
401  return nullptr;
402 
403  auto leftmost_start = aLine->m_start;
404  auto leftmost_end = aLine->m_end;
405 
406  auto rightmost_start = m_start;
407  auto rightmost_end = m_end;
408 
409  // We place the start to the left and below the end of both lines
410  if( leftmost_start != std::min( { leftmost_start, leftmost_end }, less ) )
411  std::swap( leftmost_start, leftmost_end );
412  if( rightmost_start != std::min( { rightmost_start, rightmost_end }, less ) )
413  std::swap( rightmost_start, rightmost_end );
414 
415  // -leftmost is the line that starts farthest to the left
416  // -other is the line that is _not_ leftmost
417  // -rightmost is the line that ends farthest to the right. This may or
418  // may not be 'other' as the second line may be completely covered by
419  // the first.
420  if( less( rightmost_start, leftmost_start ) )
421  {
422  std::swap( leftmost_start, rightmost_start );
423  std::swap( leftmost_end, rightmost_end );
424  }
425 
426  auto other_start = rightmost_start;
427  auto other_end = rightmost_end;
428 
429  if( less( rightmost_end, leftmost_end ) )
430  {
431  rightmost_start = leftmost_start;
432  rightmost_end = leftmost_end;
433  }
434 
435  // If we end one before the beginning of the other, no overlap is possible
436  if( less( leftmost_end, other_start ) )
437  {
438  return nullptr;
439  }
440 
441  // Search for a common end:
442  if( ( leftmost_start == other_start ) && ( leftmost_end == other_end ) ) // Trivial case
443  {
444  auto ret = new SCH_LINE( *aLine );
445  ret->SetStartPoint( leftmost_start );
446  ret->SetEndPoint( leftmost_end );
447 
448  if( IsSelected() || aLine->IsSelected() )
449  ret->SetSelected();
450 
451  return ret;
452  }
453 
454  bool colinear = false;
455 
456  /* Test alignment: */
457  if( ( leftmost_start.y == leftmost_end.y ) &&
458  ( other_start.y == other_end.y ) ) // Horizontal segment
459  {
460  colinear = ( leftmost_start.y == other_start.y );
461  }
462  else if( ( leftmost_start.x == leftmost_end.x ) &&
463  ( other_start.x == other_end.x ) ) // Vertical segment
464  {
465  colinear = ( leftmost_start.x == other_start.x );
466  }
467  else
468  {
469  // We use long long here to avoid overflow -- it enforces promotion
470  // Don't use double as we need to make a direct comparison
471  // The slope of the left-most line is dy/dx. Then we check that the slope
472  // from the left most start to the right most start is the same as well as
473  // the slope from the left most start to right most end.
474  long long dx = leftmost_end.x - leftmost_start.x;
475  long long dy = leftmost_end.y - leftmost_start.y;
476  colinear = ( ( ( other_start.y - leftmost_start.y ) * dx ==
477  ( other_start.x - leftmost_start.x ) * dy ) &&
478  ( ( other_end.y - leftmost_start.y ) * dx ==
479  ( other_end.x - leftmost_start.x ) * dy ) );
480  }
481 
482  // Make a new segment that merges the 2 segments
483  if( colinear )
484  {
485  leftmost_end = rightmost_end;
486 
487  auto ret = new SCH_LINE( *aLine );
488  ret->SetStartPoint( leftmost_start );
489  ret->SetEndPoint( leftmost_end );
490 
491  if( IsSelected() || aLine->IsSelected() )
492  ret->SetSelected();
493 
494  return ret;
495  }
496 
497  return nullptr;
498 }
499 
500 
501 void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
502 {
503  if( IsGraphicLine() )
504  return;
505 
506  if( ( GetLayer() == LAYER_BUS ) || ( GetLayer() == LAYER_WIRE ) )
507  {
509  m_start );
510  aItemList.push_back( item );
511 
513  m_end );
514  aItemList.push_back( item1 );
515  }
516 }
517 
518 
519 bool SCH_LINE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
520  const SCH_SHEET_PATH* aPath )
521 {
522  bool previousStartState = m_startIsDangling;
523  bool previousEndState = m_endIsDangling;
524 
526 
527  if( GetLayer() == LAYER_WIRE )
528  {
529  for( DANGLING_END_ITEM item : aItemList )
530  {
531  if( item.GetItem() == this )
532  continue;
533 
534  if( item.GetType() == BUS_START_END ||
535  item.GetType() == BUS_END_END ||
536  item.GetType() == BUS_ENTRY_END )
537  continue;
538 
539  if( m_start == item.GetPosition() )
540  m_startIsDangling = false;
541 
542  if( m_end == item.GetPosition() )
543  m_endIsDangling = false;
544 
546  break;
547  }
548  }
549  else if( GetLayer() == LAYER_BUS || IsGraphicLine() )
550  {
551  // Lines on the notes layer and the bus layer cannot be tested for dangling ends.
552  previousStartState = previousEndState = m_startIsDangling = m_endIsDangling = false;
553  }
554 
555  return ( previousStartState != m_startIsDangling ) || ( previousEndState != m_endIsDangling );
556 }
557 
558 
560 {
561  if( m_Layer == LAYER_WIRE || m_Layer == LAYER_BUS )
562  return true;
563 
564  return false;
565 }
566 
567 
568 bool SCH_LINE::CanConnect( const SCH_ITEM* aItem ) const
569 {
570  switch( aItem->Type() )
571  {
572  case SCH_JUNCTION_T:
573  case SCH_NO_CONNECT_T:
574  case SCH_LABEL_T:
575  case SCH_GLOBAL_LABEL_T:
576  case SCH_HIER_LABEL_T:
578  case SCH_COMPONENT_T:
579  case SCH_SHEET_T:
580  case SCH_SHEET_PIN_T:
581  return true;
582 
583  default:
584  return aItem->GetLayer() == m_Layer;
585  }
586 }
587 
588 
589 void SCH_LINE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
590 {
591  aPoints.push_back( m_start );
592  aPoints.push_back( m_end );
593 }
594 
595 
596 void SCH_LINE::GetSelectedPoints( std::vector< wxPoint >& aPoints ) const
597 {
598  if( m_Flags & STARTPOINT )
599  aPoints.push_back( m_start );
600 
601  if( m_Flags & ENDPOINT )
602  aPoints.push_back( m_end );
603 }
604 
605 
606 wxString SCH_LINE::GetSelectMenuText( EDA_UNITS aUnits ) const
607 {
608  wxString txtfmt, orient;
609 
610  if( m_start.x == m_end.x )
611  orient = _( "Vertical" );
612  else if( m_start.y == m_end.y )
613  orient = _( "Horizontal" );
614 
615  switch( m_Layer )
616  {
617  case LAYER_NOTES: txtfmt = _( "%s Graphic Line from (%s, %s) to (%s, %s)" ); break;
618  case LAYER_WIRE: txtfmt = _( "%s Wire from (%s, %s) to (%s, %s)" ); break;
619  case LAYER_BUS: txtfmt = _( "%s Bus from (%s, %s) to (%s, %s)" ); break;
620  default: txtfmt = _( "%s Line on Unknown Layer from (%s, %s) to (%s, %s)" ); break;
621  }
622 
623  return wxString::Format( txtfmt,
624  orient,
625  MessageTextFromValue( aUnits, m_start.x ),
626  MessageTextFromValue( aUnits, m_start.y ),
627  MessageTextFromValue( aUnits, m_end.x ),
628  MessageTextFromValue( aUnits, m_end.y ) );
629 }
630 
631 
633 {
634  if( m_Layer == LAYER_NOTES )
635  return add_dashed_line_xpm;
636  else if( m_Layer == LAYER_WIRE )
637  return add_line_xpm;
638 
639  return add_bus_xpm;
640 }
641 
642 
644  SCH_SHEET_PATH* aSheetPath )
645 {
646  // Net list item not required for graphic lines.
647  if( IsGraphicLine() )
648  return;
649 
650  NETLIST_OBJECT* item = new NETLIST_OBJECT();
651  item->m_SheetPath = *aSheetPath;
652  item->m_SheetPathInclude = *aSheetPath;
653  item->m_Comp = (SCH_ITEM*) this;
654  item->m_Start = m_start;
655  item->m_End = m_end;
656 
657  if( GetLayer() == LAYER_BUS )
658  {
659  item->m_Type = NETLIST_ITEM::BUS;
660  }
661  else /* WIRE */
662  {
664  }
665 
666  aNetListItems.push_back( item );
667 }
668 
669 
670 bool SCH_LINE::operator <( const SCH_ITEM& aItem ) const
671 {
672  if( Type() != aItem.Type() )
673  return Type() < aItem.Type();
674 
675  auto line = static_cast<const SCH_LINE*>( &aItem );
676 
677  if( GetLayer() != line->GetLayer() )
678  return GetLayer() < line->GetLayer();
679 
680  if( GetStartPoint().x != line->GetStartPoint().x )
681  return GetStartPoint().x < line->GetStartPoint().x;
682 
683  if( GetStartPoint().y != line->GetStartPoint().y )
684  return GetStartPoint().y < line->GetStartPoint().y;
685 
686  if( GetEndPoint().x != line->GetEndPoint().x )
687  return GetEndPoint().x < line->GetEndPoint().x;
688 
689  return GetEndPoint().y < line->GetEndPoint().y;
690 }
691 
692 
693 bool SCH_LINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
694 {
695  // Performance enhancement for connection-building
696  if( aPosition == m_start || aPosition == m_end )
697  return true;
698 
699  // Insure minimum accuracy
700  if( aAccuracy == 0 )
701  aAccuracy = ( GetPenWidth() / 2 ) + 4;
702 
703  return TestSegmentHit( aPosition, m_start, m_end, aAccuracy );
704 }
705 
706 
707 bool SCH_LINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
708 {
709  if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
710  return false;
711 
712  EDA_RECT rect = aRect;
713 
714  if ( aAccuracy )
715  rect.Inflate( aAccuracy );
716 
717  if( aContained )
718  return rect.Contains( m_start ) && rect.Contains( m_end );
719 
720  return rect.Intersects( m_start, m_end );
721 }
722 
723 
725 {
726  SCH_LINE* item = (SCH_LINE*) aItem;
727 
728  std::swap( m_Layer, item->m_Layer );
729 
730  std::swap( m_start, item->m_start );
731  std::swap( m_end, item->m_end );
732  std::swap( m_startIsDangling, item->m_startIsDangling );
733  std::swap( m_endIsDangling, item->m_endIsDangling );
734  std::swap( m_style, item->m_style );
735  std::swap( m_size, item->m_size );
736  std::swap( m_color, item->m_color );
737 }
738 
739 
740 bool SCH_LINE::doIsConnected( const wxPoint& aPosition ) const
741 {
742  if( m_Layer != LAYER_WIRE && m_Layer != LAYER_BUS )
743  return false;
744 
745  return IsEndPoint( aPosition );
746 }
747 
748 
749 void SCH_LINE::Plot( PLOTTER* aPlotter )
750 {
751  auto* settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
752  int penWidth;
753 
754  if( m_color != COLOR4D::UNSPECIFIED )
755  aPlotter->SetColor( m_color );
756  else
757  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( GetLayer() ) );
758 
759  switch( m_Layer )
760  {
761  case LAYER_WIRE: penWidth = settings->m_DefaultWireThickness; break;
762  case LAYER_BUS: penWidth = settings->m_DefaultBusThickness; break;
763  default: penWidth = GetPenWidth(); break;
764  }
765 
766  penWidth = std::max( penWidth, aPlotter->RenderSettings()->GetDefaultPenWidth() );
767 
768  aPlotter->SetCurrentLineWidth( penWidth );
769  aPlotter->SetDash( GetLineStyle() );
770 
771  aPlotter->MoveTo( m_start );
772  aPlotter->FinishTo( m_end );
773 
774  aPlotter->SetDash( PLOT_DASH_TYPE::SOLID );
775 }
776 
777 
778 void SCH_LINE::SetPosition( const wxPoint& aPosition )
779 {
780  m_end = m_end - ( m_start - aPosition );
781  m_start = aPosition;
782 }
783 
784 
786 {
787  wxString msg;
788 
789  switch( GetLayer() )
790  {
791  case LAYER_WIRE: msg = _( "Net Wire" ); break;
792  case LAYER_BUS: msg = _( "Bus Wire" ); break;
793  default: msg = _( "Graphical" ); return;
794  }
795 
796  aList.push_back( MSG_PANEL_ITEM( _( "Line Type" ), msg, DARKCYAN ) );
797 
798  SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
799 
800  if( !frame )
801  return;
802 
803  if( auto conn = Connection( frame->GetCurrentSheet() ) )
804  {
805 #if defined(DEBUG)
806  conn->AppendDebugInfoToMsgPanel( aList );
807 
808  msg.Printf( "%zu", m_connected_items.size() );
809  aList.push_back( MSG_PANEL_ITEM( _( "Connections" ), msg, BROWN ) );
810 #else
811  conn->AppendInfoToMsgPanel( aList );
812 #endif
813  }
814 }
815 
816 
818 {
819  return ( GetLayer() == LAYER_NOTES );
820 }
821 
822 
823 bool SCH_LINE::IsWire() const
824 {
825  return ( GetLayer() == LAYER_WIRE );
826 }
827 
828 
830 {
831  return m_size == 0 && m_color == COLOR4D::UNSPECIFIED
833 }
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
Definition: sch_line.cpp:333
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
Definition: sch_line.cpp:589
void FinishTo(const wxPoint &pos)
Definition: plotter.h:257
EDA_UNITS
Definition: common.h:196
SCH_LINE * MergeOverlap(SCH_LINE *aLine)
Check line against aLine to see if it overlaps and merge if it does.
Definition: sch_line.cpp:388
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points.
Definition: sch_line.cpp:501
static const char * GetLineStyleName(PLOT_DASH_TYPE aStyle)
Definition: sch_line.cpp:124
int sign(T val)
Definition: util.h:90
SCH_LAYER_ID m_Layer
Definition: sch_item.h:156
void SetModified()
Definition: base_struct.cpp:85
COLOR4D GetLineColor() const
Returns COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
Definition: sch_line.cpp:249
wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_line.h:67
bool IsGraphicLine() const
Returns if the line is a graphic (non electrical line)
Definition: sch_line.cpp:817
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:206
PNG memory record (file in memory).
Definition: bitmap_def.h:29
std::unordered_map< SCH_SHEET_PATH, ITEM_SET > m_connected_items
Stores pointers to other items that are connected to this one, per sheet.
Definition: sch_item.h:163
const BITMAP_OPAQUE add_dashed_line_xpm[1]
wxPoint GetStartPoint() const
Definition: sch_line.h:97
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
bool IsWire() const
Returns true if the line is a wire.
Definition: sch_line.cpp:823
bool IsSelected() const
Definition: base_struct.h:207
PLOT_DASH_TYPE m_style
Line style.
Definition: sch_line.h:45
Implementation of conversion functions that require both schematic and board internal units.
SCH_SHEET_PATH m_SheetPathInclude
virtual void SetColor(COLOR4D color)=0
bool m_endIsDangling
True if end point is not connected.
Definition: sch_line.h:41
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:288
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:128
void RotateEnd(wxPoint aPosition)
Definition: sch_line.cpp:346
void MoveStart(const wxPoint &aMoveVector)
Definition: sch_line.cpp:160
bool IsParallel(SCH_LINE *aLine)
Definition: sch_line.cpp:375
int color
Definition: DXF_plotter.cpp:61
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
Definition: sch_line.cpp:749
const COLOR4D & GetLayerColor(int aLayer) const
Function GetLayerColor Returns the color used to draw a layer.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: sch_line.cpp:785
Schematic editor (Eeschema) main window.
SCH_SHEET_PATH m_SheetPath
bool CanConnect(const SCH_ITEM *aItem) const override
Definition: sch_line.cpp:568
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
The base class for create windows for drawing purpose.
EDA_ITEM * m_Comp
void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers returns the layers the item is drawn on (which may be more than its "home" lay...
Definition: sch_line.cpp:197
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: sch_line.cpp:606
bool Contains(const wxPoint &aPoint) const
Function Contains.
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
Definition: sch_line.cpp:693
void RotateStart(wxPoint aPosition)
Definition: sch_line.cpp:340
bool UsesDefaultStroke() const
Test if the SCH_LINE object uses the default stroke settings.
Definition: sch_line.cpp:829
void Move(const wxPoint &aMoveVector) override
Function Move moves the item by aMoveVector to a new position.
Definition: sch_line.cpp:149
This file contains miscellaneous commonly used macros and functions.
NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected items in a...
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
void SetLineColor(const COLOR4D aColor)
Definition: sch_line.cpp:228
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:175
bool IsConnectable() const override
Function IsConnectable returns true if the schematic item can connect to another schematic item.
Definition: sch_line.cpp:559
PLOT_DASH_TYPE GetDefaultStyle() const
Definition: sch_line.cpp:255
void SetLineStyle(const PLOT_DASH_TYPE aStyle)
Definition: sch_line.cpp:270
double a
Alpha component.
Definition: color4d.h:305
void MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Definition: sch_line.cpp:319
COLOR4D m_color
Line color.
Definition: sch_line.h:46
#define NULL
const std::map< PLOT_DASH_TYPE, const char * > lineStyleNames
Definition: sch_line.cpp:116
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: sch_line.cpp:632
PLOT_DASH_TYPE GetLineStyle() const
Definition: sch_line.cpp:279
const BITMAP_OPAQUE add_line_xpm[1]
Definition: add_line.cpp:30
double GetLength() const
Definition: sch_line.cpp:222
bool m_startIsDangling
True if start point is not connected.
Definition: sch_line.h:40
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:126
int GetPenWidth() const override
Function GetPenSize virtual pure.
Definition: sch_line.cpp:294
bool IsEndPoint(const wxPoint &aPoint) const
Definition: sch_line.h:90
SCH_SHEET_PATH.
static wxPenStyle getwxPenStyle(PLOT_DASH_TYPE aType)
Definition: sch_line.cpp:47
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:230
bool doIsConnected(const wxPoint &aPosition) const override
Function doIsConnected provides the object specific test to see if it is connected to aPosition.
Definition: sch_line.cpp:740
void GetSelectedPoints(std::vector< wxPoint > &aPoints) const
Definition: sch_line.cpp:596
static PLOT_DASH_TYPE GetLineStyleByName(const wxString &aStyleName)
Definition: sch_line.cpp:134
wxPoint m_end
Line end point.
Definition: sch_line.h:43
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
Definition: sch_line.cpp:724
SCH_CONNECTION * Connection(const SCH_SHEET_PATH &aPath) const
Retrieves the connection associated with this object in the given sheet Note: the returned value can ...
Definition: sch_item.cpp:147
PLOT_DASH_TYPE
Enum for choosing dashed line type.
Definition: plotter.h:87
YYCODETYPE lhs
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
Definition: sch_item.h:241
void MoveTo(const wxPoint &pos)
Definition: plotter.h:247
bool IsSameQuadrant(SCH_LINE *aLine, const wxPoint &aPosition)
Check if two lines are in the same quadrant as each other, using a reference point as the origin.
Definition: sch_line.cpp:352
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
int m_size
Line pensize.
Definition: sch_line.h:44
Base plotter engine class.
Definition: plotter.h:104
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:137
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:38
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: sch_line.cpp:107
void MoveEnd(const wxPoint &aMoveVector)
Definition: sch_line.cpp:170
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_line.cpp:670
#define _(s)
Definition: 3d_actions.cpp:33
STATUS_FLAGS m_Flags
Definition: base_struct.h:180
#define ENDPOINT
ends. (Used to support dragging.)
Definition: base_struct.h:123
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
const BITMAP_OPAQUE add_bus_xpm[1]
Definition: add_bus.cpp:30
void Print(RENDER_SETTINGS *aSettings, const wxPoint &aOffset) override
Function Print Print a schematic item.
Definition: sch_line.cpp:303
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Definition: sch_line.cpp:326
int GetDefaultPenWidth() const
SCH_SHEET_PATH & GetCurrentSheet() const
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList, const SCH_SHEET_PATH *aPath=nullptr) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it's dangling state...
Definition: sch_line.cpp:519
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: sch_line.cpp:205
DANGLING_END_ITEM is a helper class used to store the state of schematic items that can be connected ...
Definition: sch_item.h:80
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Definition: sch_line.cpp:778
Definition of the NETLIST_OBJECT class.
NETLIST_ITEM m_Type
SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:151
wxPoint m_start
Line start point.
Definition: sch_line.h:42
SCH_LINE(const wxPoint &pos=wxPoint(0, 0), int layer=LAYER_NOTES)
Definition: sch_line.cpp:67
virtual void SetDash(PLOT_DASH_TYPE dashed)=0
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:197
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: base_struct.h:122
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
void GetNetListItem(NETLIST_OBJECT_LIST &aNetListItems, SCH_SHEET_PATH *aSheetPath) override
Function GetNetListItem creates a new NETLIST_OBJECT for the schematic object and adds it to aNetList...
Definition: sch_line.cpp:643
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40
Definition: colors.h:62
wxPoint GetEndPoint() const
Definition: sch_line.h:100