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 <class_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 
82 {
83  return wxPoint( m_pos.x + m_size.x, m_pos.y + m_size.y );
84 }
85 
86 
88 {
89  SCH_BUS_ENTRY_BASE* item = dynamic_cast<SCH_BUS_ENTRY_BASE*>( aItem );
90  wxCHECK_RET( item, wxT( "Cannot swap bus entry data with invalid item." ) );
91 
92  std::swap( m_pos, item->m_pos );
93  std::swap( m_size, item->m_size );
94 }
95 
96 
98 {
99  EDA_RECT box;
100 
101  box.SetOrigin( m_pos );
102  box.SetEnd( m_End() );
103 
104  box.Normalize();
105  box.Inflate( GetPenSize() / 2 );
106 
107  return box;
108 }
109 
110 
112 {
113  return GetDefaultLineThickness();
114 }
115 
116 
118 {
119  return GetDefaultBusThickness();
120 }
121 
122 
123 void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
124  GR_DRAWMODE aDrawMode, COLOR4D aColor )
125 {
126  COLOR4D color;
127  EDA_RECT* clipbox = aPanel->GetClipBox();
128 
129  if( aColor != COLOR4D::UNSPECIFIED )
130  color = aColor;
131  else
133 
134  GRSetDrawMode( aDC, aDrawMode );
135 
136  GRLine( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
137  m_End().x + aOffset.x, m_End().y + aOffset.y, GetPenSize(), color );
138 
139 
140  // Draw pin targets if part is being dragged
141  bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
142 
143  if( m_isDanglingStart || dragging )
144  {
145  GRCircle( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
146  TARGET_BUSENTRY_RADIUS, 0, color );
147  }
148 
149  if( m_isDanglingEnd || dragging )
150  {
151  GRCircle( clipbox, aDC, m_End().x + aOffset.x, m_End().y + aOffset.y,
152  TARGET_BUSENTRY_RADIUS, 0, color );
153  }
154 }
155 
156 
157 void SCH_BUS_ENTRY_BASE::MirrorX( int aXaxis_position )
158 {
159  MIRROR( m_pos.y, aXaxis_position );
160  m_size.y = -m_size.y;
161 }
162 
163 
164 void SCH_BUS_ENTRY_BASE::MirrorY( int aYaxis_position )
165 {
166  MIRROR( m_pos.x, aYaxis_position );
167  m_size.x = -m_size.x;
168 }
169 
170 
172 {
173  RotatePoint( &m_pos, aPosition, 900 );
174  RotatePoint( &m_size.x, &m_size.y, 900 );
175 }
176 
177 
178 void SCH_BUS_ENTRY_BASE::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
179 {
180  DANGLING_END_ITEM item( ENTRY_END, this, m_pos );
181  aItemList.push_back( item );
182 
183  DANGLING_END_ITEM item1( ENTRY_END, this, m_End() );
184  aItemList.push_back( item1 );
185 }
186 
187 
188 bool SCH_BUS_ENTRY_BASE::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
189 {
190  bool previousStateStart = m_isDanglingStart;
191  bool previousStateEnd = m_isDanglingEnd;
192 
194 
195  // Wires and buses are stored in the list as a pair, start and end. This
196  // variable holds the start position from one iteration so it can be used
197  // when the end position is found.
198  wxPoint seg_start;
199 
200  // Special case: if both items are wires, show as dangling. This is because
201  // a bus entry between two wires will look like a connection, but does NOT
202  // actually represent one. We need to clarify this for the user.
203  bool start_is_wire = false;
204  bool end_is_wire = false;
205 
206  for( DANGLING_END_ITEM& each_item : aItemList )
207  {
208  if( each_item.GetItem() == this )
209  continue;
210 
211  switch( each_item.GetType() )
212  {
213  case WIRE_START_END:
214  case BUS_START_END:
215  seg_start = each_item.GetPosition();
216  break;
217 
218  case WIRE_END_END:
219  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
220  start_is_wire = true;
221  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
222  end_is_wire = true;
223  // Fall through
224 
225  case BUS_END_END:
226  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
227  m_isDanglingStart = false;
228  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
229  m_isDanglingEnd = false;
230  break;
231  default:
232  break;
233  }
234  }
235 
236  // See above: show as dangling if joining two wires
237  if( start_is_wire && end_is_wire )
239 
240  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
241 }
242 
243 
245 {
247 }
248 
249 
250 bool SCH_BUS_ENTRY_BASE::IsSelectStateChanged( const wxRect& aRect )
251 {
252  bool previousState = IsSelected();
253 
254  // If either end of the bus entry is inside the selection rectangle, the entire
255  // bus entry is selected. Bus entries have a fixed length and angle.
256  if( aRect.Contains( m_pos ) || aRect.Contains( m_End() ) )
257  SetFlags( SELECTED );
258  else
259  ClearFlags( SELECTED );
260 
261  return previousState != IsSelected();
262 }
263 
264 
265 void SCH_BUS_ENTRY_BASE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
266 {
267  aPoints.push_back( m_pos );
268  aPoints.push_back( m_End() );
269 }
270 
271 
273 {
274  return wxString( _( "Bus to Wire Entry" ) );
275 }
276 
277 
279 {
280  return wxString( _( "Bus to Bus Entry" ) );
281 }
282 
284 {
285  return add_entry_xpm;
286 }
287 
288 
289 bool SCH_BUS_ENTRY_BASE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
290 {
291  return TestSegmentHit( aPosition, m_pos, m_End(), aAccuracy );
292 }
293 
294 
295 bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
296 {
297  EDA_RECT rect = aRect;
298 
299  rect.Inflate( aAccuracy );
300 
301  if( aContained )
302  return rect.Contains( GetBoundingBox() );
303 
304  return rect.Intersects( GetBoundingBox() );
305 }
306 
307 
309 {
310  aPlotter->SetCurrentLineWidth( GetPenSize() );
311  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
312  aPlotter->MoveTo( m_pos );
313  aPlotter->FinishTo( m_End() );
314 }
315 
316 
318 {
319  switch( aShape )
320  {
321  case '\\':
322  if( m_size.y < 0 )
323  m_size.y = -m_size.y;
324  break;
325 
326  case '/':
327  if( m_size.y > 0 )
328  m_size.y = -m_size.y;
329  break;
330  }
331 }
332 
333 
335 {
336  if( GetSize().y < 0 )
337  return '/';
338  else
339  return '\\';
340 }
void FinishTo(const wxPoint &pos)
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
PNG memory record (file in memory).
Definition: bitmap_types.h:38
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:296
EDA_ITEM * GetCurItem() const
virtual void SetColor(COLOR4D color)=0
bool Contains(const wxPoint &aPoint) const
Function Contains.
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...
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:235
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
void SetOrigin(const wxPoint &pos)
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:251
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:267
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
bool IsMouseCaptured() const
void SetEnd(int x, int y)
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 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:358
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void MoveTo(const wxPoint &pos)
void Normalize()
Function Normalize ensures that the height ant width are positive.
Base plotter engine class.
Definition: class_plotter.h:97
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
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:828
Class EDA_RECT handles the component boundary box.
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:187
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:165
The common library.
SCH_BUS_ENTRY_BASE(KICAD_T aType, const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:268
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.
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
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.
bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList) override
Function IsDanglingStateChanged tests the schematic item to aItemList to check if it's dangling state...
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
virtual int GetPenSize() const
Function GetPenSize virtual pure.
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