KiCad PCB EDA Suite
lib_rectangle.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2004-2021 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 
25 
26 #include <eda_draw_frame.h>
27 #include <sch_draw_panel.h>
28 #include <plotters/plotter.h>
29 #include <trigo.h>
30 #include <base_units.h>
31 #include <widgets/msgpanel.h>
32 #include <bitmaps.h>
33 #include <general.h>
34 #include <lib_rectangle.h>
36 #include <transform.h>
37 
38 
40 {
41  m_Width = 0;
43  m_isFillable = true;
44 }
45 
46 
48 {
49  return new LIB_RECTANGLE( *this );
50 }
51 
52 
53 int LIB_RECTANGLE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
54 {
55  wxASSERT( aOther.Type() == LIB_RECTANGLE_T );
56 
57  int retv = LIB_ITEM::compare( aOther );
58 
59  if( retv )
60  return retv;
61 
62  const LIB_RECTANGLE* tmp = ( LIB_RECTANGLE* ) &aOther;
63 
64  if( m_Pos.x != tmp->m_Pos.x )
65  return m_Pos.x - tmp->m_Pos.x;
66 
67  if( m_Pos.y != tmp->m_Pos.y )
68  return m_Pos.y - tmp->m_Pos.y;
69 
70  if( m_End.x != tmp->m_End.x )
71  return m_End.x - tmp->m_End.x;
72 
73  if( m_End.y != tmp->m_End.y )
74  return m_End.y - tmp->m_End.y;
75 
76  return 0;
77 }
78 
79 
80 void LIB_RECTANGLE::Offset( const wxPoint& aOffset )
81 {
82  m_Pos += aOffset;
83  m_End += aOffset;
84 }
85 
86 
87 void LIB_RECTANGLE::MoveTo( const wxPoint& aPosition )
88 {
89  wxPoint size = m_End - m_Pos;
90  m_Pos = aPosition;
91  m_End = aPosition + size;
92 }
93 
94 
95 void LIB_RECTANGLE::MirrorHorizontal( const wxPoint& aCenter )
96 {
97  m_Pos.x -= aCenter.x;
98  m_Pos.x *= -1;
99  m_Pos.x += aCenter.x;
100  m_End.x -= aCenter.x;
101  m_End.x *= -1;
102  m_End.x += aCenter.x;
103 }
104 
105 
106 void LIB_RECTANGLE::MirrorVertical( const wxPoint& aCenter )
107 {
108  m_Pos.y -= aCenter.y;
109  m_Pos.y *= -1;
110  m_Pos.y += aCenter.y;
111  m_End.y -= aCenter.y;
112  m_End.y *= -1;
113  m_End.y += aCenter.y;
114 }
115 
116 
117 void LIB_RECTANGLE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
118 {
119  int rot_angle = aRotateCCW ? -900 : 900;
120  RotatePoint( &m_Pos, aCenter, rot_angle );
121  RotatePoint( &m_End, aCenter, rot_angle );
122 }
123 
124 
125 void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
126  const TRANSFORM& aTransform ) const
127 {
128  wxASSERT( aPlotter != nullptr );
129 
130  wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
131  wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
132 
134  {
135  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
136  aPlotter->Rect( pos, end, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 );
137  }
138 
139  bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR;
140  int pen_size = GetEffectivePenWidth( aPlotter->RenderSettings() );
141 
142  if( !already_filled || pen_size > 0 )
143  {
144  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
145  aPlotter->Rect( pos, end, already_filled ? FILL_TYPE::NO_FILL : m_fill, pen_size );
146  }
147 }
148 
149 
151 {
152  return m_Width;
153 }
154 
155 
156 void LIB_RECTANGLE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
157  void* aData, const TRANSFORM& aTransform )
158 {
159  bool forceNoFill = static_cast<bool>( aData );
160  int penWidth = GetEffectivePenWidth( aSettings );
161 
162  if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 )
163  return;
164 
165  wxDC* DC = aSettings->GetPrintDC();
166  COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE );
167  wxPoint pt1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
168  wxPoint pt2 = aTransform.TransformCoordinate( m_End ) + aOffset;
169 
170  if( forceNoFill || m_fill == FILL_TYPE::NO_FILL )
171  {
172  GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color );
173  }
174  else
175  {
178 
179  GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color, color );
180  }
181 }
182 
183 
185 {
186  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
187 
188  wxString msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width );
189 
190  aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg ) );
191 }
192 
193 
195 {
196  EDA_RECT rect;
197 
198  rect.SetOrigin( m_Pos );
199  rect.SetEnd( m_End );
200  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
201 
202  rect.RevertYAxis();
203 
204  return rect;
205 }
206 
207 
208 bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
209 {
210  int mindist = std::max( aAccuracy + GetPenWidth() / 2,
211  Mils2iu( MINIMUM_SELECTION_DISTANCE ) );
212  wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos );
213  wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End );
214 
215  // locate lower segment
216  wxPoint start, end;
217 
218  start = actualStart;
219  end.x = actualEnd.x;
220  end.y = actualStart.y;
221 
222  if( TestSegmentHit( aPosition, start, end, mindist ) )
223  return true;
224 
225  // locate right segment
226  start.x = actualEnd.x;
227  end.y = actualEnd.y;
228 
229  if( TestSegmentHit( aPosition, start, end, mindist ) )
230  return true;
231 
232  // locate upper segment
233  start.y = actualEnd.y;
234  end.x = actualStart.x;
235 
236  if( TestSegmentHit( aPosition, start, end, mindist ) )
237  return true;
238 
239  // locate left segment
240  start = actualStart;
241  end.x = actualStart.x;
242  end.y = actualEnd.y;
243 
244  if( TestSegmentHit( aPosition, start, end, mindist ) )
245  return true;
246 
247  if( m_fill == FILL_TYPE::NO_FILL )
248  return false;
249 
250  return GetBoundingBox().Contains( aPosition );
251 }
252 
253 
254 bool LIB_RECTANGLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
255 {
256  if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )
257  return false;
258 
259  EDA_RECT sel = aRect;
260 
261  if ( aAccuracy )
262  sel.Inflate( aAccuracy );
263 
264  if( aContained )
265  return sel.Contains( GetBoundingBox() );
266 
267  return sel.Intersects( GetBoundingBox() );
268 }
269 
270 
272 {
273  return wxString::Format( _( "Rectangle, width %s height %s" ),
274  MessageTextFromValue( aUnits, std::abs( m_Pos.x - m_End.x ) ),
275  MessageTextFromValue( aUnits, std::abs( m_Pos.y - m_End.y ) ) );
276 }
277 
278 
280 {
281  return BITMAPS::add_rectangle;
282 }
283 
284 
285 void LIB_RECTANGLE::BeginEdit( const wxPoint& aPosition )
286 {
287  m_Pos = m_End = aPosition;
288 }
289 
290 
291 void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition )
292 {
293  m_End = aPosition;
294 }
void print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print the item to aDC.
void BeginEdit(const wxPoint &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Implementation of conversion functions that require both schematic and board internal units.
void GRFilledRect(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, const COLOR4D &Color, const COLOR4D &BgColor)
Definition: gr_basic.cpp:811
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
int color
Definition: DXF_plotter.cpp:57
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:121
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
virtual int GetEffectivePenWidth(const RENDER_SETTINGS *aSettings) const
Definition: lib_item.h:146
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, const COLOR4D &aColor)
Definition: gr_basic.cpp:774
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:481
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
The base class for create windows for drawing purpose.
Define a library symbol object.
Definition: lib_symbol.h:96
void RevertYAxis()
Mirror the rectangle from the X axis (negate Y pos and size).
Definition: eda_rect.h:198
FILL_TYPE m_fill
The body fill type.
Definition: lib_item.h:339
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
LIB_RECTANGLE(LIB_SYMBOL *aParent)
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
COMPARE_FLAGS
The list of flags used by the compare function.
Definition: lib_item.h:81
void SetEnd(int x, int y)
Definition: eda_rect.h:182
bool TestSegmentHit(const wxPoint &aRefPoint, const wxPoint &aStart, const wxPoint &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
#define MINIMUM_SELECTION_DISTANCE
Definition: lib_item.h:47
bool m_isFillable
Definition: lib_item.h:340
int GetPenWidth() const override
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
wxDC * GetPrintDC() const
void MirrorVertical(const wxPoint &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_item.cpp:50
virtual void SetColor(const COLOR4D &color)=0
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
EDA_UNITS
Definition: eda_units.h:38
Base plotter engine class.
Definition: plotter.h:121
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
TRANSFORM DefaultTransform
Definition: eeschema.cpp:56
#define SKIP_STRUCT
flag indicating that the structure should be ignored
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
Handle the component boundary box.
Definition: eda_rect.h:42
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:97
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
void CalcEdit(const wxPoint &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
EDA_MSG_PANEL items for displaying messages.
Definition: msgpanel.h:53
Message panel definition file.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
virtual int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:74
const EDA_RECT GetBoundingBox() const override
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void Plot(PLOTTER *aPlotter, const wxPoint &aOffset, bool aFill, const TRANSFORM &aTransform) const override
Plot the draw item using the plot object.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const override
Provide the draw object specific comparison called by the == and < operators.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103