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