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 * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.TXT for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27 #include <functional>
28 using namespace std::placeholders;
29
30 #include <board.h>
31 #include <board_item.h>
32 #include <footprint.h>
33 #include <pcb_edit_frame.h>
34 #include <pcb_group.h>
35 #include <class_draw_panel_gal.h>
36 #include <view/view_controls.h>
37 #include <view/view_group.h>
38 #include <painter.h>
39 #include <bitmaps.h>
40 #include <tool/tool_event.h>
41 #include <tool/tool_manager.h>
42 #include <tools/pcb_selection.h>
43 #include <connectivity/connectivity_data.h>
44 #include "pcb_selection_tool.h"
45 #include "pcb_actions.h"
46
47 #include "plugins/kicad/pcb_plugin.h"
48
49
50
GetTopLeftItem(bool aFootprintsOnly) const51 EDA_ITEM* PCB_SELECTION::GetTopLeftItem( bool aFootprintsOnly ) const
52 {
53 EDA_ITEM* topLeftItem = nullptr;
54
55 wxPoint pnt;
56
57 // find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item in the selection
58 for( EDA_ITEM* item : m_items )
59 {
60 pnt = item->GetPosition();
61
62 if( ( item->Type() != PCB_FOOTPRINT_T ) && aFootprintsOnly )
63 {
64 continue;
65 }
66 else
67 {
68 if( topLeftItem == nullptr )
69 {
70 topLeftItem = item;
71 }
72 else if( ( pnt.x < topLeftItem->GetPosition().x ) ||
73 ( ( topLeftItem->GetPosition().x == pnt.x ) &&
74 ( pnt.y < topLeftItem->GetPosition().y ) ) )
75 {
76 topLeftItem = item;
77 }
78 }
79 }
80
81 return topLeftItem;
82 }
83
84
updateDrawList() const85 const std::vector<KIGFX::VIEW_ITEM*> PCB_SELECTION::updateDrawList() const
86 {
87 std::vector<VIEW_ITEM*> items;
88
89 std::function<void ( EDA_ITEM* )> addItem;
90 addItem = [&]( EDA_ITEM* item )
91 {
92 items.push_back( item );
93
94 if( item->Type() == PCB_FOOTPRINT_T )
95 {
96 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
97 footprint->RunOnChildren( [&]( BOARD_ITEM* bitem )
98 {
99 addItem( bitem );
100 } );
101 }
102 else if( item->Type() == PCB_GROUP_T )
103 {
104 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
105 group->RunOnChildren( [&]( BOARD_ITEM* bitem )
106 {
107 addItem( bitem );
108 } );
109 }
110 };
111
112 for( EDA_ITEM* item : m_items )
113 addItem( item );
114
115 return items;
116 }
117
118
GetSelectionLayers()119 const LSET PCB_SELECTION::GetSelectionLayers()
120 {
121 LSET retval;
122
123 for( EDA_ITEM* item : m_items )
124 {
125 if( BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item ) )
126 retval |= board_item->GetLayerSet();
127 }
128
129 return retval;
130 }
131