KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_group_tool.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23#include <kiplatform/ui.h>
24#include <tool/tool_manager.h>
28#include <status_popup.h>
29#include <board_commit.h>
31#include <pcb_group.h>
32#include <collectors.h>
33#include <footprint.h>
34
35
37{
38 bool isFootprintEditor = m_frame->GetFrameType() == FRAME_FOOTPRINT_EDITOR;
41
42 STATUS_TEXT_POPUP statusPopup( m_frame );
43 bool done = false;
44
46 m_propertiesDialog->Show( false );
47
48 Activate();
49
50 statusPopup.SetText( _( "Click on new member..." ) );
51
52 picker->SetCursor( KICURSOR::BULLSEYE );
53 picker->SetSnapping( false );
54 picker->ClearHandlers();
55
56 picker->SetClickHandler(
57 [&]( const VECTOR2D& aPoint ) -> bool
58 {
60
61 const PCB_SELECTION& sel = selTool->RequestSelection(
62 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
63 {
64 } );
65
66 if( sel.Empty() )
67 return true; // still looking for an item
68
69 statusPopup.Hide();
70
72 {
73 EDA_ITEM* elem = sel.Front();
74
75 if( !isFootprintEditor )
76 {
77 while( elem->GetParent() && elem->GetParent()->Type() != PCB_T )
78 elem = elem->GetParent();
79 }
80
82 m_propertiesDialog->Show( true );
83 }
84
85 return false; // got our item; don't need any more
86 } );
87
88 picker->SetMotionHandler(
89 [&]( const VECTOR2D& aPos )
90 {
91 statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, -50 ) );
92 } );
93
94 picker->SetCancelHandler(
95 [&]()
96 {
97 if( m_propertiesDialog )
98 m_propertiesDialog->Show( true );
99
100 statusPopup.Hide();
101 } );
102
103 picker->SetFinalizeHandler(
104 [&]( const int& aFinalState )
105 {
106 done = true;
107 } );
108
109 statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, -50 ) );
110 statusPopup.Popup();
111 m_frame->GetCanvas()->SetStatusPopup( statusPopup.GetPanel() );
112
113 m_toolMgr->RunAction( ACTIONS::pickerTool, &aEvent );
114
115 while( !done )
116 {
117 // Pass events unless we receive a null event, then we must shut down
118 if( TOOL_EVENT* evt = Wait() )
119 evt->SetPassEvent();
120 else
121 break;
122 }
123
124 m_frame->GetCanvas()->SetStatusPopup( nullptr );
125
126 return 0;
127}
128
129
131{
132 bool isFootprintEditor = m_frame->GetFrameType() == FRAME_FOOTPRINT_EDITOR;
134 PCB_SELECTION selection;
135
136 if( isFootprintEditor )
137 {
138 selection = selTool->RequestSelection(
139 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* )
140 {
141 // Iterate from the back so we don't have to worry about removals.
142 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
143 {
144 BOARD_ITEM* item = aCollector[i];
145
146 if( !item->IsGroupableType() )
147 aCollector.Remove( item );
148 }
149 } );
150 }
151 else
152 {
153 selection = selTool->RequestSelection(
154 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* )
155 {
156 // Iterate from the back so we don't have to worry about removals.
157 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
158 {
159 BOARD_ITEM* item = aCollector[i];
160
161 if( item->GetParentFootprint() )
162 aCollector.Remove( item );
163
164 if( !item->IsGroupableType() )
165 aCollector.Remove( item );
166 }
167 } );
168 }
169
170 if( selection.Empty() )
171 return 0;
172
173 BOARD* board = getModel<BOARD>();
174 PCB_GROUP* group = nullptr;
175
176 if( isFootprintEditor )
177 group = new PCB_GROUP( board->GetFirstFootprint() );
178 else
179 group = new PCB_GROUP( board );
180
181 for( EDA_ITEM* eda_item : selection )
182 {
183 if( eda_item->IsBOARD_ITEM() )
184 {
185 if( static_cast<BOARD_ITEM*>( eda_item )->IsLocked() )
186 group->SetLocked( true );
187 }
188 }
189
190 for( EDA_ITEM* eda_item : selection )
191 {
192 if( eda_item->IsBOARD_ITEM() )
193 {
194 if( EDA_GROUP* existingGroup = eda_item->GetParentGroup() )
195 m_commit->Modify( existingGroup->AsEdaItem(), nullptr, RECURSE_MODE::NO_RECURSE );
196
197 m_commit->Modify( eda_item );
198 group->AddItem( eda_item );
199 }
200 }
201
202 m_commit->Add( group );
203 m_commit->Push( _( "Group Items" ) );
204
207
209 m_frame->OnModify();
210
211 return 0;
212}
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: actions.h:224
static TOOL_ACTION pickerTool
Definition: actions.h:250
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: actions.h:221
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
bool IsGroupableType() const
Definition: board_item.cpp:41
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:489
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:83
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:111
void DoAddMember(EDA_ITEM *aItem)
bool Show(bool show) override
FRAME_T GetFrameType() const
virtual void OnModify()
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
A set of EDA_ITEMs (i.e., without duplicates).
Definition: eda_group.h:46
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:98
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:349
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:207
DIALOG_GROUP_PROPERTIES * m_propertiesDialog
Definition: group_tool.h:79
EDA_DRAW_FRAME * m_frame
Definition: group_tool.h:78
std::shared_ptr< COMMIT > m_commit
Definition: group_tool.h:81
int PickNewMember(const TOOL_EVENT &aEvent) override
Invoke the picker tool to select a new member of the group.
int Group(const TOOL_EVENT &aEvent) override
Ungroup selected items.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:53
Generic tool for picking an item.
The selection tool: currently supports:
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection, filtered according to aClientFilter.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:115
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:83
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:220
Generic, UI-independent tool event.
Definition: tool_event.h:168
void Activate()
Run the tool.
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
#define _(s)
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: wxgtk/ui.cpp:683
Class to handle a set of BOARD_ITEMs.