KiCad PCB EDA Suite
selection.h
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) 2013-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #ifndef SELECTION_H
27 #define SELECTION_H
28 
29 #include <algorithm>
30 #include <core/optional.h>
31 #include <deque>
32 #include <eda_rect.h>
33 #include <eda_item.h>
34 #include <view/view_group.h>
35 
37 {
38 public:
41  {
42  m_isHover = false;
43  }
44 
45  SELECTION( const SELECTION& aOther ) :
47  {
48  m_items = aOther.m_items;
49  m_isHover = aOther.m_isHover;
50  }
51 
52  SELECTION& operator= ( const SELECTION& aOther )
53  {
54  m_items = aOther.m_items;
55  m_isHover = aOther.m_isHover;
56  return *this;
57  }
58 
59  using ITER = std::deque<EDA_ITEM*>::iterator;
60  using CITER = std::deque<EDA_ITEM*>::const_iterator;
61 
62  ITER begin() { return m_items.begin(); }
63  ITER end() { return m_items.end(); }
64  CITER begin() const { return m_items.cbegin(); }
65  CITER end() const { return m_items.cend(); }
66 
67  void SetIsHover( bool aIsHover )
68  {
69  m_isHover = aIsHover;
70  }
71 
72  bool IsHover() const
73  {
74  return m_isHover;
75  }
76 
77  virtual void Add( EDA_ITEM* aItem )
78  {
79  // We're not sorting here; this is just a time-optimized way to do an
80  // inclusion check. std::lower_bound will return the first i >= aItem
81  // and the second i > aItem check rules out i == aItem.
82  ITER i = std::lower_bound( m_items.begin(), m_items.end(), aItem );
83 
84  if( i == m_items.end() || *i > aItem )
85  m_items.insert( i, aItem );
86  }
87 
88  virtual void Remove( EDA_ITEM *aItem )
89  {
90  ITER i = std::lower_bound( m_items.begin(), m_items.end(), aItem );
91 
92  if( !( i == m_items.end() || *i > aItem ) )
93  m_items.erase( i );
94  }
95 
96  virtual void Clear() override
97  {
98  m_items.clear();
99  }
100 
101  virtual unsigned int GetSize() const override
102  {
103  return m_items.size();
104  }
105 
106  virtual KIGFX::VIEW_ITEM* GetItem( unsigned int aIdx ) const override
107  {
108  if( aIdx < m_items.size() )
109  return m_items[ aIdx ];
110 
111  return nullptr;
112  }
113 
114  bool Contains( EDA_ITEM* aItem ) const
115  {
116  CITER i = std::lower_bound( m_items.begin(), m_items.end(), aItem );
117 
118  return !( i == m_items.end() || *i > aItem );
119  }
120 
122  bool Empty() const
123  {
124  return m_items.empty();
125  }
126 
128  int Size() const
129  {
130  return m_items.size();
131  }
132 
133  const std::deque<EDA_ITEM*> GetItems() const
134  {
135  return m_items;
136  }
137 
139  virtual VECTOR2I GetCenter() const
140  {
142  bool includeLabels = true;
143 
144  // If the selection contains at least one non-label then don't include labels when
145  // calculating the centerpoint.
146 
147  for( EDA_ITEM* item : m_items )
148  {
149  if( !item->IsType( labelTypes ) )
150  {
151  includeLabels = false;
152  break;
153  }
154  }
155 
156  EDA_RECT bbox;
157 
158  for( EDA_ITEM* item : m_items )
159  {
160  if( !item->IsType( labelTypes ) || includeLabels )
161  bbox.Merge( item->GetBoundingBox() );
162  }
163 
164  return static_cast<VECTOR2I>( bbox.Centre() );
165  }
166 
167  virtual const BOX2I ViewBBox() const override
168  {
169  BOX2I r;
170  r.SetMaximum();
171  return r;
172  }
173 
176  {
177  return static_cast<VECTOR2I>( GetBoundingBox().GetPosition() );
178  }
179 
180  virtual EDA_RECT GetBoundingBox() const
181  {
182  EDA_RECT bbox;
183 
184  for( EDA_ITEM* item : m_items )
185  bbox.Merge( item->GetBoundingBox() );
186 
187  return bbox;
188  }
189 
190  virtual EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const
191  {
192  return nullptr;
193  }
194 
195  EDA_ITEM* operator[]( const size_t aIdx ) const
196  {
197  if( aIdx < m_items.size() )
198  return m_items[ aIdx ];
199 
200  return nullptr;
201  }
202 
203  EDA_ITEM* Front() const
204  {
205  return m_items.size() ? m_items.front() : nullptr;
206  }
207 
208  std::deque<EDA_ITEM*>& Items()
209  {
210  return m_items;
211  }
212 
213  template<class T>
214  T* FirstOfKind() const
215  {
216  auto refType = T( nullptr ).Type();
217 
218  for( auto item : m_items )
219  {
220  if( item->Type() == refType )
221  return static_cast<T*> ( item );
222  }
223 
224  return nullptr;
225  }
226 
233  bool HasType( KICAD_T aType ) const
234  {
235  for( auto item : m_items )
236  {
237  if( item->Type() == aType )
238  return true;
239  }
240 
241  return false;
242  }
243 
244  virtual const VIEW_GROUP::ITEMS updateDrawList() const override
245  {
246  std::vector<VIEW_ITEM*> items;
247 
248  for( auto item : m_items )
249  items.push_back( item );
250 
251  return items;
252  }
253 
254  bool HasReferencePoint() const
255  {
256  return m_referencePoint != NULLOPT;
257  }
258 
260  {
261  return *m_referencePoint;
262  }
263 
264  void SetReferencePoint( const VECTOR2I& aP )
265  {
266  m_referencePoint = aP;
267  }
268 
270  {
272  }
273 
279  bool AreAllItemsIdentical() const
280  {
281  return ( std::all_of( m_items.begin() + 1, m_items.end(),
282  [&]( const EDA_ITEM* r )
283  {
284  return r->Type() == m_items.front()->Type();
285  } ) );
286  }
287 
288 protected:
290  std::deque<EDA_ITEM*> m_items;
291  bool m_isHover;
292 
293  // mute hidden overloaded virtual function warnings
294  using VIEW_GROUP::Add;
295  using VIEW_GROUP::Remove;
296 };
297 
298 
299 #endif
VECTOR2I GetReferencePoint() const
Definition: selection.h:259
void ClearReferencePoint()
Definition: selection.h:269
bool m_isHover
Definition: selection.h:291
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:96
bool IsHover() const
Definition: selection.h:72
void Merge(const EDA_RECT &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: eda_rect.cpp:431
std::deque< EDA_ITEM * > & Items()
Definition: selection.h:208
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.h:233
VECTOR2I GetPosition() const
Returns the top left point of the selection area bounding box.
Definition: selection.h:175
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.h:139
ITER end()
Definition: selection.h:63
std::deque< EDA_ITEM * >::const_iterator CITER
Definition: selection.h:60
bool AreAllItemsIdentical() const
Checks if all items in the selection are the same KICAD_T type.
Definition: selection.h:279
An abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:81
OPT< VECTOR2I > m_referencePoint
Definition: selection.h:289
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
void SetIsHover(bool aIsHover)
Definition: selection.h:67
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:77
CITER end() const
Definition: selection.h:65
ITER begin()
Definition: selection.h:62
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:264
SELECTION(const SELECTION &aOther)
Definition: selection.h:45
const auto NULLOPT
Definition: optional.h:9
std::deque< EDA_ITEM * > m_items
Definition: selection.h:290
SELECTION()
Definition: selection.h:39
virtual EDA_RECT GetBoundingBox() const
Definition: selection.h:180
void SetMaximum()
Definition: box2.h:73
bool Contains(EDA_ITEM *aItem) const
Definition: selection.h:114
const std::deque< EDA_ITEM * > GetItems() const
Definition: selection.h:133
Extend VIEW_ITEM by possibility of grouping items into a single object.
Definition: view_group.h:46
std::deque< EDA_ITEM * >::iterator ITER
Definition: selection.h:59
virtual EDA_ITEM * GetTopLeftItem(bool onlyModules=false) const
Definition: selection.h:190
VIEW_GROUP(VIEW *aView=NULL)
Definition: view_group.cpp:43
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:106
virtual const VIEW_GROUP::ITEMS updateDrawList() const override
Layer on which the group is drawn.
Definition: selection.h:244
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
EDA_ITEM * operator[](const size_t aIdx) const
Definition: selection.h:195
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:101
bool HasReferencePoint() const
Definition: selection.h:254
Handle the component boundary box.
Definition: eda_rect.h:42
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
wxPoint Centre() const
Definition: eda_rect.h:60
boost::optional< T > OPT
Definition: optional.h:7
T * FirstOfKind() const
Definition: selection.h:214
SELECTION & operator=(const SELECTION &aOther)
Definition: selection.h:52
CITER begin() const
Definition: selection.h:64
EDA_ITEM * Front() const
Definition: selection.h:203
virtual const BOX2I ViewBBox() const override
Return the bounding box for all stored items covering all its layers.
Definition: selection.h:167
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.h:88