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 <painter.h>
28 #include <math/util.h> // for KiROUND
29 #include "tool/edit_points.h"
30 
31 bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
32 {
33  // Corners of the EDIT_POINT square
34  VECTOR2I topLeft = GetPosition() - aSize;
35  VECTOR2I bottomRight = GetPosition() + aSize;
36 
37  return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y &&
38  aPoint.x < bottomRight.x && aPoint.y < bottomRight.y );
39 }
40 
41 
43  : EDA_ITEM( NOT_USED ), m_parent( aParent ), m_allowPoints( true )
44 {
45 }
46 
47 
48 EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation, KIGFX::VIEW *aView ) // fixme: ugly
49 {
50  unsigned size = std::abs( KiROUND( aView->ToWorld( EDIT_POINT::POINT_SIZE ) ) );
51 
52  if( m_allowPoints )
53  {
54  for( auto& point : m_points )
55  {
56  if( point.WithinPoint( aLocation, size ) )
57  return &point;
58  }
59  }
60 
61  for( auto& line : m_lines )
62  {
63  if( line.WithinPoint( aLocation, size ) )
64  return &line;
65  }
66 
67  return NULL;
68 }
69 
70 
71 int EDIT_POINTS::GetContourStartIdx( int aPointIdx ) const
72 {
73  int lastIdx = 0;
74 
75  for( int idx : m_contours )
76  {
77  if( idx >= aPointIdx )
78  return lastIdx;
79 
80  lastIdx = idx + 1;
81  }
82 
83  return lastIdx;
84 }
85 
86 
87 int EDIT_POINTS::GetContourEndIdx( int aPointIdx ) const
88 {
89  for( int idx : m_contours )
90  {
91  if( idx >= aPointIdx )
92  return idx;
93  }
94 
95  return m_points.size() - 1;
96 }
97 
98 
99 bool EDIT_POINTS::IsContourStart( int aPointIdx ) const
100 {
101  for( int idx : m_contours )
102  {
103  if( idx + 1 == aPointIdx )
104  return true;
105 
106  // the list is sorted, so we cannot expect it any further
107  if( idx > aPointIdx )
108  break;
109  }
110 
111  return ( aPointIdx == 0 );
112 }
113 
114 
115 bool EDIT_POINTS::IsContourEnd( int aPointIdx ) const
116 {
117  for( int idx : m_contours )
118  {
119  if( idx == aPointIdx )
120  return true;
121 
122  // the list is sorted, so we cannot expect it any further
123  if( idx > aPointIdx )
124  break;
125  }
126 
127  // the end of the list surely is the end of a contour
128  return ( aPointIdx == (int) m_points.size() - 1 );
129 }
130 
131 
132 EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint, bool aTraverseContours )
133 {
134  for( unsigned int i = 0; i < m_points.size(); ++i )
135  {
136  if( m_points[i] == aPoint )
137  {
138  if( !aTraverseContours && IsContourStart( i ) )
139  return &m_points[GetContourEndIdx( i )];
140 
141  if( i == 0 )
142  return &m_points[m_points.size() - 1];
143  else
144  return &m_points[i - 1];
145  }
146  }
147 
148  return NULL;
149 }
150 
151 
153 {
154  for( unsigned int i = 0; i < m_lines.size(); ++i )
155  {
156  if( m_lines[i] == aLine )
157  {
158  if( i == 0 )
159  return &m_lines[m_lines.size() - 1];
160  else
161  return &m_lines[i - 1];
162  }
163  }
164 
165  return NULL;
166 }
167 
168 
169 EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint, bool aTraverseContours )
170 {
171  for( unsigned int i = 0; i < m_points.size(); ++i )
172  {
173  if( m_points[i] == aPoint )
174  {
175  if( !aTraverseContours && IsContourEnd( i ) )
176  return &m_points[GetContourStartIdx( i )];
177 
178  if( i == m_points.size() - 1 )
179  return &m_points[0];
180  else
181  return &m_points[i + 1];
182  }
183  }
184 
185  return NULL;
186 }
187 
188 
190 {
191  for( unsigned int i = 0; i < m_lines.size(); ++i )
192  {
193  if( m_lines[i] == aLine )
194  {
195  if( i == m_lines.size() - 1 )
196  return &m_lines[0];
197  else
198  return &m_lines[i + 1];
199  }
200  }
201 
202  return NULL;
203 }
204 
205 
207 {
208  BOX2I box;
209  bool empty = true;
210 
211  for( const auto& point : m_points )
212  {
213  if( empty )
214  {
215  box.SetOrigin( point.GetPosition() );
216  empty = false;
217  }
218  else
219  {
220  box.Merge( point.GetPosition() );
221  }
222  }
223 
224  for( const auto& line : m_lines )
225  {
226  if( empty )
227  {
228  box.SetOrigin( line.GetOrigin().GetPosition() );
229  box.SetEnd( line.GetEnd().GetPosition() );
230  empty = false;
231  }
232  else
233  {
234  box.Merge( line.GetOrigin().GetPosition() );
235  box.Merge( line.GetEnd().GetPosition() );
236  }
237  }
238 
239  return box;
240 }
241 
242 
243 void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
244 {
245  auto gal = aView->GetGAL();
246 
247  KIGFX::RENDER_SETTINGS* settings = aView->GetPainter()->GetSettings();
248 
249  KIGFX::COLOR4D drawColor = settings->GetLayerColor( LAYER_AUX_ITEMS );
250  KIGFX::COLOR4D bgColor = drawColor.Darkened( 0.3 ).WithAlpha( 0.8 );
251  KIGFX::COLOR4D highlightColor = settings->GetLayerColor( LAYER_SELECT_OVERLAY );
252 
253  gal->SetFillColor( drawColor );
254  gal->SetStrokeColor( bgColor );
255  gal->SetIsFill( true );
256  gal->SetIsStroke( true );
257  gal->PushDepth();
258  gal->SetLayerDepth( gal->GetMinDepth() );
259 
260  double size = aView->ToWorld( EDIT_POINT::POINT_SIZE ) / 2.0;
261  double borderSize = aView->ToWorld( EDIT_POINT::BORDER_SIZE );
262  double hoverSize = aView->ToWorld( EDIT_POINT::HOVER_SIZE );
263 
264  auto drawPoint =
265  [&]( const EDIT_POINT& aPoint, bool aDrawCircle = false )
266  {
267  if( aPoint.IsHover() || aPoint.IsActive() )
268  {
269  gal->SetStrokeColor( highlightColor );
270  gal->SetLineWidth( hoverSize );
271  }
272  else
273  {
274  gal->SetStrokeColor( bgColor );
275  gal->SetLineWidth( borderSize );
276  }
277 
278  gal->SetFillColor( aPoint.IsActive() ? highlightColor : drawColor );
279 
280  if( aDrawCircle )
281  gal->DrawCircle( aPoint.GetPosition(), size );
282  else
283  gal->DrawRectangle( aPoint.GetPosition() - size, aPoint.GetPosition() + size );
284  };
285 
286  for( const EDIT_POINT& point : m_points )
287  drawPoint( point );
288 
289  for( const EDIT_LINE& line : m_lines )
290  drawPoint( line, true );
291 
292  gal->PopDepth();
293 }
int GetContourEndIdx(int aPointIdx) const
Function GetContourEndIdx()
Definition: edit_points.cpp:87
std::list< int > m_contours
Indices of end contour points.
Definition: edit_points.h:566
std::deque< EDIT_POINT > m_points
EDIT_POINTs for modifying m_parent.
Definition: edit_points.h:564
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
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:456
std::deque< EDIT_LINE > m_lines
EDIT_LINEs for modifying m_parent.
Definition: edit_points.h:565
the 3d code uses this value
Definition: typeinfo.h:80
EDIT_LINE.
Definition: edit_points.h:226
EDIT_POINT * Next(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Function Next()
virtual const BOX2I ViewBBox() const override
static const int BORDER_SIZE
Border size when not hovering
Definition: edit_points.h:200
bool m_allowPoints
If false, only allow editing of EDIT_LINES.
Definition: edit_points.h:567
bool IsContourStart(int aPointIdx) const
Function IsContourStart()
Definition: edit_points.cpp:99
const COLOR4D & GetLayerColor(int aLayer) const
Function GetLayerColor Returns the color used to draw a layer.
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:315
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:182
bool IsContourEnd(int aPointIdx) const
Function IsContourEnd()
COLOR4D Darkened(double aFactor) const
Function Darkened Returns a color that is darker by a given factor, without modifying object.
Definition: color4d.h:283
virtual void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:201
bool IsActive() const
Definition: edit_points.h:182
Auxiliary items (guides, rule, etc)
EDIT_POINT * FindPoint(const VECTOR2I &aLocation, KIGFX::VIEW *aView)
Function FindPoint()
Definition: edit_points.cpp:48
virtual VECTOR2I GetPosition() const
Function GetPosition()
Definition: edit_points.h:71
#define NULL
int GetContourStartIdx(int aPointIdx) const
Function GetContourStartIdx()
Definition: edit_points.cpp:71
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:386
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:225
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
void SetOrigin(const Vec &pos)
Definition: box2.h:210
currently selected items overlay
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:68
EDIT_POINTS(EDA_ITEM *aParent)
Constructor.
Definition: edit_points.cpp:42
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:148
static const int POINT_SIZE
Single point size in pixels
Definition: edit_points.h:197
EDIT_POINT * Previous(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Function Previous()
EDIT_POINT.
Definition: edit_points.h:46
bool IsHover() const
Definition: edit_points.h:185
VIEW.
Definition: view.h:63
static const int HOVER_SIZE
Border size when hovering
Definition: edit_points.h:203
bool WithinPoint(const VECTOR2I &aPoint, unsigned int aSize) const
Function WithinPoint()
Definition: edit_points.cpp:31
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:100