KiCad PCB EDA Suite
class_edge_mod.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, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
32 #include <fctsys.h>
33 #include <gr_basic.h>
34 #include <wxstruct.h>
35 #include <trigo.h>
36 #include <class_drawpanel.h>
37 #include <class_pcb_screen.h>
38 #include <confirm.h>
39 #include <kicad_string.h>
40 #include <colors_selection.h>
41 #include <richio.h>
42 #include <macros.h>
43 #include <math_for_graphics.h>
44 #include <wxBasePcbFrame.h>
45 #include <msgpanel.h>
46 #include <base_units.h>
47 #include <bitmaps.h>
48 
49 #include <class_board.h>
50 #include <class_module.h>
51 #include <class_edge_mod.h>
52 
53 #include <stdio.h>
54 
57 {
58  m_Shape = aShape;
59  m_Angle = 0;
60  m_Layer = F_SilkS;
61 }
62 
63 
65 {
66 }
67 
68 
70 {
71  MODULE* module = (MODULE*) m_Parent;
72 
73  if( module == NULL )
74  {
75  m_Start0 = m_Start;
76  m_End0 = m_End;
77  return;
78  }
79 
80  m_Start0 = m_Start - module->GetPosition();
81  m_End0 = m_End - module->GetPosition();
82  double angle = module->GetOrientation();
83  RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
84  RotatePoint( &m_End0.x, &m_End0.y, -angle );
85 }
86 
87 
89 {
90  MODULE* module = (MODULE*) m_Parent;
91 
92  m_Start = m_Start0;
93  m_End = m_End0;
94 
95  if( module )
96  {
97  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
98  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
99 
100  m_Start += module->GetPosition();
101  m_End += module->GetPosition();
102  }
103 }
104 
105 
106 void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
107  const wxPoint& offset )
108 {
109  int ux0, uy0, dx, dy, radius, StAngle, EndAngle;
110  LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
111 
112  MODULE* module = (MODULE*) m_Parent;
113 
114  if( !module )
115  return;
116 
117  BOARD* brd = GetBoard( );
118 
119  if( brd->IsLayerVisible( m_Layer ) == false )
120  return;
121 
122  COLOR4D color = brd->GetLayerColor( m_Layer );
123  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
124 
125  if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
126  {
127  if( !IsOnLayer( curr_layer ) )
128  color = COLOR4D( DARKDARKGRAY );
129  }
130 
131  ux0 = m_Start.x - offset.x;
132  uy0 = m_Start.y - offset.y;
133 
134  dx = m_End.x - offset.x;
135  dy = m_End.y - offset.y;
136 
137  GRSetDrawMode( DC, draw_mode );
138  bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED;
139 
140  if( IsCopperLayer( m_Layer ) )
141  filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED;
142 
143  switch( m_Shape )
144  {
145  case S_SEGMENT:
146  if( filled )
147  GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
148  else
149  // SKETCH Mode
150  GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
151 
152  break;
153 
154  case S_CIRCLE:
155  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
156 
157  if( filled )
158  {
159  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
160  }
161  else // SKETCH Mode
162  {
163  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color );
164  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color );
165  }
166 
167  break;
168 
169  case S_ARC:
170  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
171  StAngle = ArcTangente( dy - uy0, dx - ux0 );
172  EndAngle = StAngle + m_Angle;
173 
174  if( !panel->GetPrintMirrored() )
175  {
176  if( StAngle > EndAngle )
177  std::swap( StAngle, EndAngle );
178  }
179  else // Mirrored mode: arc orientation is reversed
180  {
181  if( StAngle < EndAngle )
182  std::swap( StAngle, EndAngle );
183  }
184 
185  if( filled )
186  {
187  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color );
188  }
189  else // SKETCH Mode
190  {
191  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
192  radius + (m_Width / 2), color );
193  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
194  radius - (m_Width / 2), color );
195  }
196  break;
197 
198  case S_POLYGON:
199  {
200  // We must compute absolute coordinates from m_PolyPoints
201  // which are relative to module position, orientation 0
202  std::vector<wxPoint> points = m_PolyPoints;
203 
204  for( unsigned ii = 0; ii < points.size(); ii++ )
205  {
206  wxPoint& pt = points[ii];
207 
208  RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
209  pt += module->GetPosition() - offset;
210  }
211 
212  GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color );
213  }
214  break;
215 
216  default:
217  break;
218  }
219 }
220 
221 
222 // see class_edge_mod.h
223 void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
224 {
225  wxString msg;
226 
227  MODULE* module = (MODULE*) m_Parent;
228 
229  if( !module )
230  return;
231 
232  BOARD* board = (BOARD*) module->GetParent();
233 
234  if( !board )
235  return;
236 
237  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) );
238  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) );
239  msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() );
240  aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) );
241  aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ),
242  module->GetLayerName(), RED ) );
243 
244  // append the features shared with the base class
246 }
247 
248 
249 
251 {
252  wxString text;
253  text.Printf( _( "Graphic (%s) on %s of %s" ),
254  GetChars( ShowShape( m_Shape ) ),
255  GetChars( GetLayerName() ),
256  GetChars( ((MODULE*) GetParent())->GetReference() ) );
257 
258  return text;
259 }
260 
261 
263 {
264  return show_mod_edge_xpm;
265 }
266 
267 
269 {
270  return new EDGE_MODULE( *this );
271 }
272 
273 
274 void EDGE_MODULE::Flip( const wxPoint& aCentre )
275 {
276  wxPoint pt;
277 
278  switch( GetShape() )
279  {
280  case S_ARC:
281  SetAngle( -GetAngle() );
282  //Fall through
283  default:
284  case S_SEGMENT:
285  pt = GetStart();
286  MIRROR( pt.y, aCentre.y );
287  SetStart( pt );
288 
289  pt = GetEnd();
290  MIRROR( pt.y, aCentre.y );
291  SetEnd( pt );
292 
293  MIRROR( m_Start0.y, 0 );
294  MIRROR( m_End0.y, 0 );
295  break;
296 
297  case S_POLYGON:
298  // polygon corners coordinates are always relative to the
299  // footprint position, orientation 0
300  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
301  MIRROR( m_PolyPoints[ii].y, 0 );
302  }
303 
304  // DRAWSEGMENT items are not usually on copper layers, but
305  // it can happen in microwave apps.
306  // However, currently, only on Front or Back layers.
307  // So the copper layers count is not taken in account
308  SetLayer( FlipLayer( GetLayer() ) );
309 }
310 
311 
312 void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
313 {
314  // Mirror an edge of the footprint. the layer is not modified
315  // This is a footprint shape modification.
316  switch( GetShape() )
317  {
318  case S_ARC:
319  SetAngle( -GetAngle() );
320  //Fall through
321  default:
322  case S_SEGMENT:
323  if( aMirrorAroundXAxis )
324  {
325  MIRROR( m_Start0.y, aCentre.y );
326  MIRROR( m_End0.y, aCentre.y );
327  }
328  else
329  {
330  MIRROR( m_Start0.x, aCentre.x );
331  MIRROR( m_End0.x, aCentre.x );
332  }
333  break;
334 
335  case S_POLYGON:
336  // polygon corners coordinates are always relative to the
337  // footprint position, orientation 0
338  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
339  {
340  if( aMirrorAroundXAxis )
341  MIRROR( m_PolyPoints[ii].y, aCentre.y );
342  else
343  MIRROR( m_PolyPoints[ii].x, aCentre.x );
344  }
345  }
346 
347  SetDrawCoord();
348 }
349 
350 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
351 {
352  // We should rotate the relative coordinates, but to avoid duplicate code,
353  // do the base class rotation of draw coordinates, which is acceptable
354  // because in module editor, m_Pos0 = m_Pos
355  DRAWSEGMENT::Rotate( aRotCentre, aAngle );
356 
357  // and now update the relative coordinates, which are
358  // the reference in most transforms.
359  SetLocalCoord();
360 }
361 
362 
363 void EDGE_MODULE::Move( const wxPoint& aMoveVector )
364 {
365  // Move an edge of the footprint.
366  // This is a footprint shape modification.
367  m_Start0 += aMoveVector;
368  m_End0 += aMoveVector;
369 
370  switch( GetShape() )
371  {
372  default:
373  break;
374 
375  case S_POLYGON:
376  // polygon corners coordinates are always relative to the
377  // footprint position, orientation 0
378  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
379  m_PolyPoints[ii] += aMoveVector;
380  }
381 
382  SetDrawCoord();
383 }
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: colors.h:57
BOARD_ITEM_CONTAINER * GetParent() const
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
void GRPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:767
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:168
virtual void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
PNG memory record (file in memory).
Definition: bitmap_types.h:38
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:143
polygon (not yet used for tracks, but could be in microwave apps)
COLOR4D GetLayerColor(LAYER_ID aLayer) const
Function GetLayerColor gets a layer color for any valid layer, including non-copper ones...
virtual void SetLayer(LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:481
bool m_DisplayModEdgeFill
Definition: pcbstruct.h:69
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:439
usual segment : line with rounded ends
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
double m_Angle
Used only for Arcs: Arc angle in 1/10 deg.
LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
wxPoint m_End0
This file contains miscellaneous commonly used macros and functions.
virtual bool IsOnLayer(LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
void Mirror(const wxPoint aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
bool m_DisplayPcbTrackFill
Definition: pcbstruct.h:71
LAYER_ID m_Layer
STROKE_T GetShape() const
wxPoint m_Start
Line start point or Circle and Arc center.
Classes used in Pcbnew, CvPcb and GerbView.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
wxPoint m_End
Line end point or circle and arc start point.
double GetOrientation() const
Definition: class_module.h:147
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
Base window classes and related definitions.
Arcs (with rounded ends)
void GRArc(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, double StAngle, double EndAngle, int r, COLOR4D Color)
Definition: gr_basic.cpp:982
bool m_ContrastModeDisplay
Definition: pcbstruct.h:85
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
EDA_RECT * GetClipBox()
STROKE_T m_Shape
Shape: line, Circle, Arc.
Definition: colors.h:60
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void Flip(const wxPoint &aCentre) override
Flip entity relative to aCentre.
void SetStart(const wxPoint &aStart)
time_t GetTimeStamp() const
Definition: base_struct.h:204
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
bool IsLayerVisible(LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:440
void SetLocalCoord()
Set relative coordinates from draw coordinates.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
double GetAngle() const
bool GetPrintMirrored() const
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
LAYER_ID FlipLayer(LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:444
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:411
LAYER_ID
Enum LAYER_ID is the set of PCB layers.
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:791
EDGE_MODULE(MODULE *parent, STROKE_T aShape=S_SEGMENT)
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:188
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
void SetEnd(const wxPoint &aEnd)
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees...
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
int m_Width
thickness of lines ...
Module description (excepted pads)
wxPoint m_Start0
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:182
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
std::vector< wxPoint > m_PolyPoints
double Distance(double x1, double y1, double x2, double y2)
EDGE_MODULE class definition.
Message panel definition file.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62