KiCad PCB EDA Suite
sch_bus_entry.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) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2004-2017 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 <class_drawpanel.h>
34 #include <trigo.h>
35 #include <common.h>
36 #include <richio.h>
37 #include <plotter.h>
38 #include <bitmaps.h>
39 
40 #include <eeschema_config.h>
41 #include <general.h>
42 #include <sch_bus_entry.h>
43 
44 
45 SCH_BUS_ENTRY_BASE::SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos, char shape ) :
46  SCH_ITEM( NULL, aType )
47 {
48  m_pos = pos;
49  m_size.x = 100;
50  m_size.y = 100;
51 
52  if( shape == '/' )
53  m_size.y = -100;
54 
56 }
57 
60 {
62 }
63 
64 SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, char shape ) :
66 {
68 }
69 
71 {
72  return new SCH_BUS_WIRE_ENTRY( *this );
73 }
74 
76 {
77  return new SCH_BUS_BUS_ENTRY( *this );
78 }
79 
80 
81 bool SCH_BUS_ENTRY_BASE::doIsConnected( const wxPoint& aPosition ) const
82 {
83  return ( m_pos == aPosition || m_End() == aPosition );
84 }
85 
86 
88 {
89  return wxPoint( m_pos.x + m_size.x, m_pos.y + m_size.y );
90 }
91 
92 
94 {
95  SCH_BUS_ENTRY_BASE* item = dynamic_cast<SCH_BUS_ENTRY_BASE*>( aItem );
96  wxCHECK_RET( item, wxT( "Cannot swap bus entry data with invalid item." ) );
97 
98  std::swap( m_pos, item->m_pos );
99  std::swap( m_size, item->m_size );
100 }
101 
102 
104 {
105  EDA_RECT box;
106 
107  box.SetOrigin( m_pos );
108  box.SetEnd( m_End() );
109 
110  box.Normalize();
111  box.Inflate( GetPenSize() / 2 );
112 
113  return box;
114 }
115 
116 
118 {
119  return GetDefaultLineThickness();
120 }
121 
122 
124 {
125  return GetDefaultBusThickness();
126 }
127 
128 
129 void SCH_BUS_WIRE_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
130 {
131  DANGLING_END_ITEM item( WIRE_ENTRY_END, this, m_pos );
132  aItemList.push_back( item );
133 
134  DANGLING_END_ITEM item1( WIRE_ENTRY_END, this, m_End() );
135  aItemList.push_back( item1 );
136 }
137 
138 
139 void SCH_BUS_BUS_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
140 {
141  DANGLING_END_ITEM item( BUS_ENTRY_END, this, m_pos );
142  aItemList.push_back( item );
143 
144  DANGLING_END_ITEM item1( BUS_ENTRY_END, this, m_End() );
145  aItemList.push_back( item1 );
146 }
147 
148 
149 void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
150  GR_DRAWMODE aDrawMode, COLOR4D aColor )
151 {
152  COLOR4D color;
153  EDA_RECT* clipbox = aPanel->GetClipBox();
154 
155  if( aColor != COLOR4D::UNSPECIFIED )
156  color = aColor;
157  else
159 
160  GRSetDrawMode( aDC, aDrawMode );
161 
162  GRLine( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
163  m_End().x + aOffset.x, m_End().y + aOffset.y, GetPenSize(), color );
164 
165 
166  // Draw pin targets if part is being dragged
167  bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
168 
169  if( m_isDanglingStart || dragging )
170  {
171  GRCircle( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
172  TARGET_BUSENTRY_RADIUS, 0, color );
173  }
174 
175  if( m_isDanglingEnd || dragging )
176  {
177  GRCircle( clipbox, aDC, m_End().x + aOffset.x, m_End().y + aOffset.y,
178  TARGET_BUSENTRY_RADIUS, 0, color );
179  }
180 }
181 
182 
183 void SCH_BUS_ENTRY_BASE::MirrorX( int aXaxis_position )
184 {
185  MIRROR( m_pos.y, aXaxis_position );
186  m_size.y = -m_size.y;
187 }
188 
189 
190 void SCH_BUS_ENTRY_BASE::MirrorY( int aYaxis_position )
191 {
192  MIRROR( m_pos.x, aYaxis_position );
193  m_size.x = -m_size.x;
194 }
195 
196 
198 {
199  RotatePoint( &m_pos, aPosition, 900 );
200  RotatePoint( &m_size.x, &m_size.y, 900 );
201 }
202 
203 
204 bool SCH_BUS_WIRE_ENTRY::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
205 {
206  bool previousStateStart = m_isDanglingStart;
207  bool previousStateEnd = m_isDanglingEnd;
208 
210 
211  // Wires and buses are stored in the list as a pair, start and end. This
212  // variable holds the start position from one iteration so it can be used
213  // when the end position is found.
214  wxPoint seg_start;
215 
216  // Store the connection type and state for the start (0) and end (1)
217  bool has_wire[2] = { false };
218  bool has_bus[2] = { false };
219 
220  for( DANGLING_END_ITEM& each_item : aItemList )
221  {
222  if( each_item.GetItem() == this )
223  continue;
224 
225  switch( each_item.GetType() )
226  {
227  case WIRE_START_END:
228  case BUS_START_END:
229  seg_start = each_item.GetPosition();
230  break;
231 
232  case WIRE_END_END:
233  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
234  has_wire[0] = true;
235 
236  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
237  has_wire[1] = true;
238 
239  break;
240 
241  case BUS_END_END:
242  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
243  has_bus[0] = true;
244 
245  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
246  has_bus[1] = true;
247 
248  break;
249 
250  default:
251  break;
252  }
253  }
254 
259  if( ( has_wire[0] && has_bus[1] ) || ( has_wire[1] && has_bus[0] ) )
261  else if( has_wire[0] || has_bus[0] )
262  m_isDanglingStart = false;
263  else if( has_wire[1] || has_bus[1] )
264  m_isDanglingEnd = false;
265 
266  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
267 }
268 
269 
270 bool SCH_BUS_BUS_ENTRY::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
271 {
272  bool previousStateStart = m_isDanglingStart;
273  bool previousStateEnd = m_isDanglingEnd;
274 
276 
277  // Wires and buses are stored in the list as a pair, start and end. This
278  // variable holds the start position from one iteration so it can be used
279  // when the end position is found.
280  wxPoint seg_start;
281 
282  for( DANGLING_END_ITEM& each_item : aItemList )
283  {
284  if( each_item.GetItem() == this )
285  continue;
286 
287  switch( each_item.GetType() )
288  {
289  case BUS_START_END:
290  seg_start = each_item.GetPosition();
291  break;
292  case BUS_END_END:
293  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
294  m_isDanglingStart = false;
295  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
296  m_isDanglingEnd = false;
297  break;
298  default:
299  break;
300  }
301  }
302 
303  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
304 }
305 
306 
308 {
310 }
311 
312 
313 bool SCH_BUS_ENTRY_BASE::IsSelectStateChanged( const wxRect& aRect )
314 {
315  bool previousState = IsSelected();
316 
317  // If either end of the bus entry is inside the selection rectangle, the entire
318  // bus entry is selected. Bus entries have a fixed length and angle.
319  if( aRect.Contains( m_pos ) || aRect.Contains( m_End() ) )
320  SetFlags( SELECTED );
321  else
322  ClearFlags( SELECTED );
323 
324  return previousState != IsSelected();
325 }
326 
327 
328 void SCH_BUS_ENTRY_BASE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
329 {
330  aPoints.push_back( m_pos );
331  aPoints.push_back( m_End() );
332 }
333 
334 
336 {
337  return wxString( _( "Bus to Wire Entry" ) );
338 }
339 
340 
342 {
343  return wxString( _( "Bus to Bus Entry" ) );
344 }
345 
346 
348 {
349  return add_line2bus_xpm;
350 }
351 
352 
354 {
355  return add_bus2bus_xpm;
356 }
357 
358 
359 bool SCH_BUS_ENTRY_BASE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
360 {
361  return TestSegmentHit( aPosition, m_pos, m_End(), aAccuracy );
362 }
363 
364 
365 bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
366 {
367  EDA_RECT rect = aRect;
368 
369  rect.Inflate( aAccuracy );
370 
371  if( aContained )
372  return rect.Contains( GetBoundingBox() );
373 
374  return rect.Intersects( GetBoundingBox() );
375 }
376 
377 
379 {
380  aPlotter->SetCurrentLineWidth( GetPenSize() );
381  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
382  aPlotter->MoveTo( m_pos );
383  aPlotter->FinishTo( m_End() );
384 }
385 
386 
388 {
389  switch( aShape )
390  {
391  case '\\':
392  if( m_size.y < 0 )
393  m_size.y = -m_size.y;
394  break;
395 
396  case '/':
397  if( m_size.y > 0 )
398  m_size.y = -m_size.y;
399  break;
400  }
401 }
402 
403 
405 {
406  if( GetSize().y < 0 )
407  return '/';
408  else
409  return '\\';
410 }
void FinishTo(const wxPoint &pos)
Definition: plotter.h:250
wxSize GetSize() const
Definition: sch_bus_entry.h:77
SCH_LAYER_ID m_Layer
bool IsPointOnSegment(const wxPoint &aSegStart, const wxPoint &aSegEnd, const wxPoint &aTestPoint)
Function IsPointOnSegment.
Definition: trigo.cpp:39
#define TARGET_BUSENTRY_RADIUS
Definition: sch_bus_entry.h:35
bool doIsConnected(const wxPoint &aPosition) const override
Function doIsConnected provides the object specific test to see if it is connected to aPosition...
PNG memory record (file in memory).
Definition: bitmap_types.h:41
int GetPenSize() const override
Function GetPenSize virtual pure.
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:318
EDA_ITEM * GetCurItem() const
Definition: base_screen.h:233
virtual void SetColor(COLOR4D color)=0
bool Contains(const wxPoint &aPoint) const
Function Contains.
int color
Definition: DXF_plotter.cpp:62
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i...
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
bool IsSelected() const
Definition: base_struct.h:250
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:124
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
wxPoint m_pos
Definition: sch_bus_entry.h:44
wxPoint m_End() const
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
wxSize m_size
Definition: sch_bus_entry.h:45
int GetState(int type) const
Definition: base_struct.h:266
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:167
char GetBusEntryShape() const
function GetBusEntryShape
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
This file contains miscellaneous commonly used macros and functions.
SCH_BUS_BUS_ENTRY(const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:41
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
#define SELECTED
Definition: base_struct.h:134
SCH_BUS_WIRE_ENTRY(const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
bool IsDangling() const override
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:282
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
bool IsMouseCaptured() const
void SetEnd(int x, int y)
Definition: eda_rect.h:134
bool IsSelectStateChanged(const wxRect &aRect) override
Function IsSelectStateChanged checks if the selection state of an item inside aRect has changed...
bool m_isDanglingStart
Definition: sch_bus_entry.h:46
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:151
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
EDA_RECT * GetClipBox()
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...
void SetBusEntryShape(char aShape)
function SetBusEntryShape
bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it&#39;s dangling state...
int GetPenSize() const override
Function GetPenSize virtual pure.
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:380
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void MoveTo(const wxPoint &pos)
Definition: plotter.h:240
void Normalize()
Function Normalize ensures that the height ant width are positive.
Base plotter engine class.
Definition: plotter.h:96
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
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...
void MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:850
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
bool m_isDanglingEnd
Definition: sch_bus_entry.h:46
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item...
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:194
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:180
The common library.
SCH_BUS_ENTRY_BASE(KICAD_T aType, const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
Class for a wire to bus entry.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:283
bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it&#39;s dangling state...
Class DANGLING_END_ITEM is a helper class used to store the state of schematic items that can be conn...
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED) override
Function Draw Draw a schematic item.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:142
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
int GetDefaultBusThickness()
Default line thickness used to draw/plot busses.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39