KiCad PCB EDA Suite
edit_points.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) 2014-2019 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
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 
26 #include <gal/color4d.h>
27 #include <math/util.h> // for KiROUND
28 #include "tool/edit_points.h"
29 
30 bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
31 {
32  // Corners of the EDIT_POINT square
33  VECTOR2I topLeft = GetPosition() - aSize;
34  VECTOR2I bottomRight = GetPosition() + aSize;
35 
36  return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y &&
37  aPoint.x < bottomRight.x && aPoint.y < bottomRight.y );
38 }
39 
40 
42  : EDA_ITEM( NOT_USED ), m_parent( aParent ), m_allowPoints( true )
43 {
44 }
45 
46 
47 EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation, KIGFX::VIEW *aView ) // fixme: ugly
48 {
49  unsigned size = std::abs( KiROUND( aView->ToWorld( EDIT_POINT::POINT_SIZE ) ) );
50 
51  if( m_allowPoints )
52  {
53  for( auto& point : m_points )
54  {
55  if( point.WithinPoint( aLocation, size ) )
56  return &point;
57  }
58  }
59 
60  for( auto& line : m_lines )
61  {
62  if( line.WithinPoint( aLocation, size ) )
63  return &line;
64  }
65 
66  return NULL;
67 }
68 
69 
70 int EDIT_POINTS::GetContourStartIdx( int aPointIdx ) const
71 {
72  int lastIdx = 0;
73 
74  for( int idx : m_contours )
75  {
76  if( idx >= aPointIdx )
77  return lastIdx;
78 
79  lastIdx = idx + 1;
80  }
81 
82  return lastIdx;
83 }
84 
85 
86 int EDIT_POINTS::GetContourEndIdx( int aPointIdx ) const
87 {
88  for( int idx : m_contours )
89  {
90  if( idx >= aPointIdx )
91  return idx;
92  }
93 
94  return m_points.size() - 1;
95 }
96 
97 
98 bool EDIT_POINTS::IsContourStart( int aPointIdx ) const
99 {
100  for( int idx : m_contours )
101  {
102  if( idx + 1 == aPointIdx )
103  return true;
104 
105  // the list is sorted, so we cannot expect it any further
106  if( idx > aPointIdx )
107  break;
108  }
109 
110  return ( aPointIdx == 0 );
111 }
112 
113 
114 bool EDIT_POINTS::IsContourEnd( int aPointIdx ) const
115 {
116  for( int idx : m_contours )
117  {
118  if( idx == aPointIdx )
119  return true;
120 
121  // the list is sorted, so we cannot expect it any further
122  if( idx > aPointIdx )
123  break;
124  }
125 
126  // the end of the list surely is the end of a contour
127  return ( aPointIdx == (int) m_points.size() - 1 );
128 }
129 
130 
131 EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint, bool aTraverseContours )
132 {
133  for( unsigned int i = 0; i < m_points.size(); ++i )
134  {
135  if( m_points[i] == aPoint )
136  {
137  if( !aTraverseContours && IsContourStart( i ) )
138  return &m_points[GetContourEndIdx( i )];
139 
140  if( i == 0 )
141  return &m_points[m_points.size() - 1];
142  else
143  return &m_points[i - 1];
144  }
145  }
146 
147  return NULL;
148 }
149 
150 
152 {
153  for( unsigned int i = 0; i < m_lines.size(); ++i )
154  {
155  if( m_lines[i] == aLine )
156  {
157  if( i == 0 )
158  return &m_lines[m_lines.size() - 1];
159  else
160  return &m_lines[i - 1];
161  }
162  }
163 
164  return NULL;
165 }
166 
167 
168 EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint, bool aTraverseContours )
169 {
170  for( unsigned int i = 0; i < m_points.size(); ++i )
171  {
172  if( m_points[i] == aPoint )
173  {
174  if( !aTraverseContours && IsContourEnd( i ) )
175  return &m_points[GetContourStartIdx( i )];
176 
177  if( i == m_points.size() - 1 )
178  return &m_points[0];
179  else
180  return &m_points[i + 1];
181  }
182  }
183 
184  return NULL;
185 }
186 
187 
189 {
190  for( unsigned int i = 0; i < m_lines.size(); ++i )
191  {
192  if( m_lines[i] == aLine )
193  {
194  if( i == m_lines.size() - 1 )
195  return &m_lines[0];
196  else
197  return &m_lines[i + 1];
198  }
199  }
200 
201  return NULL;
202 }
203 
204 
206 {
207  BOX2I box;
208  bool empty = true;
209 
210  for( const auto& point : m_points )
211  {
212  if( empty )
213  {
214  box.SetOrigin( point.GetPosition() );
215  empty = false;
216  }
217  else
218  {
219  box.Merge( point.GetPosition() );
220  }
221  }
222 
223  for( const auto& line : m_lines )
224  {
225  if( empty )
226  {
227  box.SetOrigin( line.GetOrigin().GetPosition() );
228  box.SetEnd( line.GetEnd().GetPosition() );
229  empty = false;
230  }
231  else
232  {
233  box.Merge( line.GetOrigin().GetPosition() );
234  box.Merge( line.GetEnd().GetPosition() );
235  }
236  }
237 
238  return box;
239 }
240 
241 
242 void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
243 {
244  auto gal = aView->GetGAL();
245 
246  if( aView->GetGAL()->GetClearColor().GetBrightness() > 0.5 )
247  gal->SetFillColor( KIGFX::COLOR4D( 0, 0, 0, 1.0 ) );
248  else
249  gal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
250  gal->SetIsFill( true );
251  gal->SetIsStroke( false );
252  gal->PushDepth();
253  gal->SetLayerDepth( gal->GetMinDepth() );
254 
255  float size = aView->ToWorld( EDIT_POINT::POINT_SIZE );
256 
257  for( const EDIT_POINT& point : m_points )
258  gal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 );
259 
260  for( const EDIT_LINE& line : m_lines )
261  {
262  gal->DrawCircle( line.GetPosition(), size / 2 );
263  }
264 
265  gal->PopDepth();
266 }
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
double GetBrightness() const
Function GetBrightness Returns the brightness value of the color ranged from 0.0 to 1....
Definition: color4d.h:270
int GetContourEndIdx(int aPointIdx) const
Function GetContourEndIdx()
Definition: edit_points.cpp:86
std::list< int > m_contours
Indices of end contour points.
Definition: edit_points.h:544
std::deque< EDIT_POINT > m_points
EDIT_POINTs for modifying m_parent.
Definition: edit_points.h:542
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:475
std::deque< EDIT_LINE > m_lines
EDIT_LINEs for modifying m_parent.
Definition: edit_points.h:543
the 3d code uses this value
Definition: typeinfo.h:80
EDIT_LINE.
Definition: edit_points.h:207
EDIT_POINT * Next(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Function Next()
virtual const BOX2I ViewBBox() const override
bool m_allowPoints
If false, only allow editing of EDIT_LINES.
Definition: edit_points.h:545
bool IsContourStart(int aPointIdx) const
Function IsContourStart()
Definition: edit_points.cpp:98
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
bool IsContourEnd(int aPointIdx) const
Function IsContourEnd()
virtual void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
EDIT_POINT * FindPoint(const VECTOR2I &aLocation, KIGFX::VIEW *aView)
Function FindPoint()
Definition: edit_points.cpp:47
virtual VECTOR2I GetPosition() const
Function GetPosition()
Definition: edit_points.h:68
#define NULL
int GetContourStartIdx(int aPointIdx) const
Function GetContourStartIdx()
Definition: edit_points.cpp:70
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
Definition: box2.h:385
const COLOR4D & GetClearColor() const
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:224
void SetOrigin(const Vec &pos)
Definition: box2.h:209
static bool empty(const wxTextEntryBase *aCtrl)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
EDIT_POINTS(EDA_ITEM *aParent)
Constructor.
Definition: edit_points.cpp:41
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
static const int POINT_SIZE
Single point size in pixels
Definition: edit_points.h:185
EDIT_POINT * Previous(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Function Previous()
EDIT_POINT.
Definition: edit_points.h:46
VIEW.
Definition: view.h:61
bool WithinPoint(const VECTOR2I &aPoint, unsigned int aSize) const
Function WithinPoint()
Definition: edit_points.cpp:30
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40