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, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2004-2011 KiCad Developers, see change_log.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 <plot_common.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 
97 bool SCH_BUS_WIRE_ENTRY::Save( FILE* aFile ) const
98 {
99  if( fprintf( aFile, "Entry Wire Line\n\t%-4d %-4d %-4d %-4d\n",
100  m_pos.x, m_pos.y, m_End().x, m_End().y ) == EOF )
101  return false;
102  return true;
103 }
104 
105 
106 bool SCH_BUS_BUS_ENTRY::Save( FILE* aFile ) const
107 {
108  if( fprintf( aFile, "Entry Bus Bus\n\t%-4d %-4d %-4d %-4d\n",
109  m_pos.x, m_pos.y, m_End().x, m_End().y ) == EOF )
110  return false;
111  return true;
112 }
113 
114 
115 bool SCH_BUS_ENTRY_BASE::Load( LINE_READER& aLine, wxString& aErrorMsg,
116  SCH_ITEM **out )
117 {
118  char Name1[256];
119  char Name2[256];
120  char* line = (char*) aLine;
121  *out = NULL;
122 
123  while( (*line != ' ' ) && *line )
124  line++;
125 
126  if( sscanf( line, "%255s %255s", Name1, Name2 ) != 2 )
127  {
128  aErrorMsg.Printf( wxT( "Eeschema file bus entry load error at line %d" ),
129  aLine.LineNumber() );
130  aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
131  return false;
132  }
133 
134  SCH_BUS_ENTRY_BASE *this_new;
135  if( Name1[0] == 'B' )
136  this_new = new SCH_BUS_BUS_ENTRY;
137  else
138  this_new = new SCH_BUS_WIRE_ENTRY;
139  *out = this_new;
140 
141  if( !aLine.ReadLine() || sscanf( (char*) aLine, "%d %d %d %d ",
142  &this_new->m_pos.x, &this_new->m_pos.y,
143  &this_new->m_size.x, &this_new->m_size.y ) != 4 )
144  {
145  aErrorMsg.Printf( wxT( "Eeschema file bus entry load error at line %d" ),
146  aLine.LineNumber() );
147  aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
148  return false;
149  }
150 
151  this_new->m_size.x -= this_new->m_pos.x;
152  this_new->m_size.y -= this_new->m_pos.y;
153 
154  return true;
155 }
156 
157 
159 {
160  EDA_RECT box;
161 
162  box.SetOrigin( m_pos );
163  box.SetEnd( m_End() );
164 
165  box.Normalize();
166  box.Inflate( GetPenSize() / 2 );
167 
168  return box;
169 }
170 
171 
173 {
174  return GetDefaultLineThickness();
175 }
176 
177 
179 {
180  return GetDefaultBusThickness();
181 }
182 
183 
184 void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
185  GR_DRAWMODE aDrawMode, COLOR4D aColor )
186 {
187  COLOR4D color;
188  EDA_RECT* clipbox = aPanel->GetClipBox();
189 
190  if( aColor != COLOR4D::UNSPECIFIED )
191  color = aColor;
192  else
194 
195  GRSetDrawMode( aDC, aDrawMode );
196 
197  GRLine( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
198  m_End().x + aOffset.x, m_End().y + aOffset.y, GetPenSize(), color );
199 
200 
201  // Draw pin targets if part is being dragged
202  bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
203 
204  if( m_isDanglingStart || dragging )
205  {
206  GRCircle( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
207  TARGET_BUSENTRY_RADIUS, 0, color );
208  }
209 
210  if( m_isDanglingEnd || dragging )
211  {
212  GRCircle( clipbox, aDC, m_End().x + aOffset.x, m_End().y + aOffset.y,
213  TARGET_BUSENTRY_RADIUS, 0, color );
214  }
215 }
216 
217 
218 void SCH_BUS_ENTRY_BASE::MirrorX( int aXaxis_position )
219 {
220  MIRROR( m_pos.y, aXaxis_position );
221  m_size.y = -m_size.y;
222 }
223 
224 
225 void SCH_BUS_ENTRY_BASE::MirrorY( int aYaxis_position )
226 {
227  MIRROR( m_pos.x, aYaxis_position );
228  m_size.x = -m_size.x;
229 }
230 
231 
233 {
234  RotatePoint( &m_pos, aPosition, 900 );
235  RotatePoint( &m_size.x, &m_size.y, 900 );
236 }
237 
238 
239 void SCH_BUS_ENTRY_BASE::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
240 {
241  DANGLING_END_ITEM item( ENTRY_END, this, m_pos );
242  aItemList.push_back( item );
243 
244  DANGLING_END_ITEM item1( ENTRY_END, this, m_End() );
245  aItemList.push_back( item1 );
246 }
247 
248 
249 bool SCH_BUS_ENTRY_BASE::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
250 {
251  bool previousStateStart = m_isDanglingStart;
252  bool previousStateEnd = m_isDanglingEnd;
253 
255 
256  // Wires and buses are stored in the list as a pair, start and end. This
257  // variable holds the start position from one iteration so it can be used
258  // when the end position is found.
259  wxPoint seg_start;
260 
261  // Special case: if both items are wires, show as dangling. This is because
262  // a bus entry between two wires will look like a connection, but does NOT
263  // actually represent one. We need to clarify this for the user.
264  bool start_is_wire = false;
265  bool end_is_wire = false;
266 
267  for( DANGLING_END_ITEM& each_item : aItemList )
268  {
269  if( each_item.GetItem() == this )
270  continue;
271 
272  switch( each_item.GetType() )
273  {
274  case WIRE_START_END:
275  case BUS_START_END:
276  seg_start = each_item.GetPosition();
277  break;
278 
279  case WIRE_END_END:
280  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
281  start_is_wire = true;
282  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
283  end_is_wire = true;
284  // Fall through
285 
286  case BUS_END_END:
287  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
288  m_isDanglingStart = false;
289  if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
290  m_isDanglingEnd = false;
291  break;
292  default:
293  break;
294  }
295  }
296 
297  // See above: show as dangling if joining two wires
298  if( start_is_wire && end_is_wire )
300 
301  return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
302 }
303 
304 
306 {
308 }
309 
310 
311 bool SCH_BUS_ENTRY_BASE::IsSelectStateChanged( const wxRect& aRect )
312 {
313  bool previousState = IsSelected();
314 
315  // If either end of the bus entry is inside the selection rectangle, the entire
316  // bus entry is selected. Bus entries have a fixed length and angle.
317  if( aRect.Contains( m_pos ) || aRect.Contains( m_End() ) )
318  SetFlags( SELECTED );
319  else
320  ClearFlags( SELECTED );
321 
322  return previousState != IsSelected();
323 }
324 
325 
326 void SCH_BUS_ENTRY_BASE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
327 {
328  aPoints.push_back( m_pos );
329  aPoints.push_back( m_End() );
330 }
331 
332 
334 {
335  return wxString( _( "Bus to Wire Entry" ) );
336 }
337 
338 
340 {
341  return wxString( _( "Bus to Bus Entry" ) );
342 }
343 
345 {
346  return add_entry_xpm;
347 }
348 
349 
350 bool SCH_BUS_ENTRY_BASE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
351 {
352  return TestSegmentHit( aPosition, m_pos, m_End(), aAccuracy );
353 }
354 
355 
356 bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
357 {
358  EDA_RECT rect = aRect;
359 
360  rect.Inflate( aAccuracy );
361 
362  if( aContained )
363  return rect.Contains( GetBoundingBox() );
364 
365  return rect.Intersects( GetBoundingBox() );
366 }
367 
368 
370 {
371  aPlotter->SetCurrentLineWidth( GetPenSize() );
372  aPlotter->SetColor( GetLayerColor( GetLayer() ) );
373  aPlotter->MoveTo( m_pos );
374  aPlotter->FinishTo( m_End() );
375 }
376 
377 /* SetBusEntryShape:
378  * Set the shape of the bus entry.
379  * aShape = ascii code '/' or '\'
380  */
382 {
383  switch( aShape )
384  {
385  case '\\':
386  if( m_size.y < 0 )
387  m_size.y = -m_size.y;
388  break;
389 
390  case '/':
391  if( m_size.y > 0 )
392  m_size.y = -m_size.y;
393  break;
394  }
395 }
396 
397 
398 /* GetBusEntryShape:
399  * return the shape of the bus entry, as an ascii code '/' or '\'
400  */
402 {
403  if( GetSize().y < 0 )
404  return '/';
405  else
406  return '\\';
407 }
408 
void FinishTo(const wxPoint &pos)
Definition: plot_common.h:241
Class SCH_BUS_WIRE_ENTRY.
wxSize GetSize() const
Definition: sch_bus_entry.h:79
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
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
PNG memory record (file in memory).
Definition: bitmap_types.h:38
int GetPenSize() const override
Function GetPenSize virtual pure.
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
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:290
EDA_ITEM * GetCurItem() const
virtual void SetColor(COLOR4D color)=0
bool Contains(const wxPoint &aPoint) const
Function Contains.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
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:221
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:46
wxPoint m_End() const
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
wxSize m_size
Definition: sch_bus_entry.h:47
int GetState(int type) const
Definition: base_struct.h:237
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:166
char GetBusEntryShape() const
function GetBusEntryShape
bool Save(FILE *aFile) const override
Function Save writes the data structures for this object out to a FILE in "*.sch" format...
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:90
This file contains miscellaneous commonly used macros and functions.
SCH_BUS_BUS_ENTRY(const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
Class SCH_BUS_ENTRY_BASE.
Definition: sch_bus_entry.h:43
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:120
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:253
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:48
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:137
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
EDA_RECT * GetClipBox()
Common plot library Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) ...
void SetBusEntryShape(char aShape)
function SetBusEntryShape
int GetPenSize() const override
Function GetPenSize virtual pure.
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...
static bool Load(LINE_READER &aLine, wxString &aErrorMsg, SCH_ITEM **out)
void MoveTo(const wxPoint &pos)
Definition: plot_common.h:231
void Normalize()
Function Normalize ensures that the height ant width are positive.
Base plotter engine class.
Definition: plot_common.h:86
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
virtual char * ReadLine()=0
Function ReadLine reads a line of text into the buffer and increments the line number counter...
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:791
Class EDA_RECT handles the component boundary box.
bool m_isDanglingEnd
Definition: sch_bus_entry.h:48
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:188
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:151
The common library.
SCH_BUS_ENTRY_BASE(KICAD_T aType, const wxPoint &pos=wxPoint(0, 0), char shape= '\\')
Class SCH_BUS_WIRE_ENTRY.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:254
Class DANGLING_END_ITEM is a helper class used to store the state of schematic items that can be conn...
bool Save(FILE *aFile) const override
Function Save writes the data structures for this object out to a FILE in "*.sch" format...
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