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 <sch_draw_panel.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 
103 void SCH_BUS_ENTRY_BASE::ViewGetLayers( int aLayers[], int& aCount ) const
104 {
105  aCount = 1;
106 
107  aLayers[0] = Type() == SCH_BUS_BUS_ENTRY_T ? LAYER_BUS : LAYER_WIRE;
108 }
109 
110 
112 {
113  EDA_RECT box;
114 
115  box.SetOrigin( m_pos );
116  box.SetEnd( m_End() );
117 
118  box.Normalize();
119  box.Inflate( GetPenSize() / 2 );
120 
121  return box;
122 }
123 
124 
126 {
127  return GetDefaultLineThickness();
128 }
129 
130 
132 {
133  return GetDefaultBusThickness();
134 }
135 
136 
137 void SCH_BUS_WIRE_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
138 {
139  DANGLING_END_ITEM item( WIRE_ENTRY_END, this, m_pos );
140  aItemList.push_back( item );
141 
142  DANGLING_END_ITEM item1( WIRE_ENTRY_END, this, m_End() );
143  aItemList.push_back( item1 );
144 }
145 
146 
147 void SCH_BUS_BUS_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
148 {
149  DANGLING_END_ITEM item( BUS_ENTRY_END, this, m_pos );
150  aItemList.push_back( item );
151 
152  DANGLING_END_ITEM item1( BUS_ENTRY_END, this, m_End() );
153  aItemList.push_back( item1 );
154 }
155 
156 
157 void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
158  GR_DRAWMODE aDrawMode, COLOR4D aColor )
159 {
160  COLOR4D color;
161  EDA_RECT* clipbox = aPanel->GetClipBox();
162 
163  if( aColor != COLOR4D::UNSPECIFIED )
164  color = aColor;
165  else
167 
168  GRSetDrawMode( aDC, aDrawMode );
169 
170  GRLine( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
171  m_End().x + aOffset.x, m_End().y + aOffset.y, GetPenSize(), color );
172 
173 
174  // Draw pin targets if part is being dragged
175  bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
176 
177  if( m_isDanglingStart || dragging )
178  {
179  GRCircle( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
180  TARGET_BUSENTRY_RADIUS, 0, color );
181  }
182 
183  if( m_isDanglingEnd || dragging )
184  {
185  GRCircle( clipbox, aDC, m_End().x + aOffset.x, m_End().y + aOffset.y,
186  TARGET_BUSENTRY_RADIUS, 0, color );
187  }
188 }
189 
190 
191 void SCH_BUS_ENTRY_BASE::MirrorX( int aXaxis_position )
192 {
193  MIRROR( m_pos.y, aXaxis_position );
194  m_size.y = -m_size.y;
195 }
196 
197 
198 void SCH_BUS_ENTRY_BASE::MirrorY( int aYaxis_position )
199 {
200  MIRROR( m_pos.x, aYaxis_position );
201  m_size.x = -m_size.x;
202 }
203 
204 
206 {
207  RotatePoint( &m_pos, aPosition, 900 );
208  RotatePoint( &m_size.x, &m_size.y, 900 );
209 }
210 
211 
212 bool SCH_BUS_WIRE_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
213 {
214  bool previousStateStart = m_isDanglingStart;
215  bool previousStateEnd = m_isDanglingEnd;
216 
218 
219  // Wires and buses are stored in the list as a pair, start and end. This
220  // variable holds the start position from one iteration so it can be used
221  // when the end position is found.
222  wxPoint seg_start;
223 
224  // Store the connection type and state for the start (0) and end (1)
225  bool has_wire[2] = { false };
226  bool has_bus[2] = { false };
227 
228  for( DANGLING_END_ITEM& each_item : aItemList )
229  {
230  if( each_item.GetItem() == this )
231  continue;
232 
233  switch( each_item.GetType() )
234  {
235  case WIRE_START_END:
236  case BUS_START_END:
237  seg_start = each_item.GetPosition();
238  break;
239 
240  case WIRE_END_END:
241  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
242  has_wire[0] = true;
243 
244  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
245  has_wire[1] = true;
246 
247  break;
248 
249  case BUS_END_END:
250  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
251  has_bus[0] = true;
252 
253  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
254  has_bus[1] = true;
255 
256  break;
257 
258  default:
259  break;
260  }
261  }
262 
267  if( ( has_wire[0] && has_bus[1] ) || ( has_wire[1] && has_bus[0] ) )
269  else if( has_wire[0] || has_bus[0] )
270  m_isDanglingStart = false;
271  else if( has_wire[1] || has_bus[1] )
272  m_isDanglingEnd = false;
273 
274  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
275 }
276 
277 
278 bool SCH_BUS_BUS_ENTRY::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
279 {
280  bool previousStateStart = m_isDanglingStart;
281  bool previousStateEnd = m_isDanglingEnd;
282 
284 
285  // Wires and buses are stored in the list as a pair, start and end. This
286  // variable holds the start position from one iteration so it can be used
287  // when the end position is found.
288  wxPoint seg_start;
289 
290  for( DANGLING_END_ITEM& each_item : aItemList )
291  {
292  if( each_item.GetItem() == this )
293  continue;
294 
295  switch( each_item.GetType() )
296  {
297  case BUS_START_END:
298  seg_start = each_item.GetPosition();
299  break;
300  case BUS_END_END:
301  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
302  m_isDanglingStart = false;
303  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
304  m_isDanglingEnd = false;
305  break;
306  default:
307  break;
308  }
309  }
310 
311  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
312 }
313 
314 
316 {
318 }
319 
320 
321 bool SCH_BUS_ENTRY_BASE::IsSelectStateChanged( const wxRect& aRect )
322 {
323  bool previousState = IsSelected();
324 
325  // If either end of the bus entry is inside the selection rectangle, the entire
326  // bus entry is selected. Bus entries have a fixed length and angle.
327  if( aRect.Contains( m_pos ) || aRect.Contains( m_End() ) )
328  SetFlags( SELECTED );
329  else
330  ClearFlags( SELECTED );
331 
332  return previousState != IsSelected();
333 }
334 
335 
336 void SCH_BUS_ENTRY_BASE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
337 {
338  aPoints.push_back( m_pos );
339  aPoints.push_back( m_End() );
340 }
341 
342 
344 {
345  return wxString( _( "Bus to Wire Entry" ) );
346 }
347 
348 
350 {
351  return wxString( _( "Bus to Bus Entry" ) );
352 }
353 
354 
356 {
357  return add_line2bus_xpm;
358 }
359 
360 
362 {
363  return add_bus2bus_xpm;
364 }
365 
366 
367 bool SCH_BUS_ENTRY_BASE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
368 {
369  return TestSegmentHit( aPosition, m_pos, m_End(), aAccuracy );
370 }
371 
372 
373 bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
374 {
375  EDA_RECT rect = aRect;
376 
377  rect.Inflate( aAccuracy );
378 
379  if( aContained )
380  return rect.Contains( GetBoundingBox() );
381 
382  return rect.Intersects( GetBoundingBox() );
383 }
384 
385 
387 {
388  aPlotter->SetCurrentLineWidth( GetPenSize() );
389  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
390  aPlotter->MoveTo( m_pos );
391  aPlotter->FinishTo( m_End() );
392 }
393 
394 
396 {
397  switch( aShape )
398  {
399  case '\\':
400  if( m_size.y < 0 )
401  m_size.y = -m_size.y;
402  break;
403 
404  case '/':
405  if( m_size.y > 0 )
406  m_size.y = -m_size.y;
407  break;
408  }
409 }
410 
411 
413 {
414  if( GetSize().y < 0 )
415  return '/';
416  else
417  return '\\';
418 }
virtual BASE_SCREEN * GetScreen()=0
void FinishTo(const wxPoint &pos)
Definition: plotter.h:251
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
wxSize GetSize() const
Definition: sch_bus_entry.h:80
SCH_LAYER_ID m_Layer
bool IsPointOnSegment(const wxPoint &aSegStart, const wxPoint &aSegEnd, const wxPoint &aTestPoint)
Function IsPointOnSegment.
Definition: trigo.cpp:39
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it&#39;s dangling state...
#define TARGET_BUSENTRY_RADIUS
Definition: sch_bus_entry.h:35
wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
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:43
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:223
EDA_ITEM * GetCurItem() const
Definition: base_screen.h:233
virtual void SetColor(COLOR4D color)=0
bool Contains(const wxPoint &aPoint) const
Function Contains.
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it&#39;s dangling state...
int color
Definition: DXF_plotter.cpp:62
void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i...
bool IsSelected() const
Definition: base_struct.h:224
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
virtual EDA_RECT * GetClipBox()
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
wxSize m_size
Definition: sch_bus_entry.h:45
int GetState(int type) const
Definition: base_struct.h:240
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:174
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:121
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:256
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
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:138
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
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:285
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:241
void Normalize()
Function Normalize ensures that the height ant width are positive.
Base plotter engine class.
Definition: plotter.h:97
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:755
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...
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:154
The common library.
SCH_BUS_ENTRY_BASE(KICAD_T aType, const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
wxString GetSelectMenuText(EDA_UNITS_T aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Class for a wire to bus entry.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
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:122
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_UNITS_T
Definition: common.h:159
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