KiCad PCB EDA Suite
gerbview_selection_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 (C) 2017 Jon Evans <[email protected]>
5 * Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <limits>
22#include <functional>
23using namespace std::placeholders;
24#include <bitmaps.h>
25#include <eda_item.h>
26#include <gerber_collectors.h>
27#include <gerbview_settings.h>
29#include <string_utils.h>
30#include <view/view.h>
31#include <view/view_group.h>
32#include <painter.h>
33#include <tool/tool_event.h>
34#include <tool/tool_manager.h>
36#include "gerbview_actions.h"
37
38
40{
41public:
43 ACTION_MENU( true )
44 {
46 SetTitle( _( "Highlight" ) );
47 }
48
49private:
50
51 void update() override
52 {
53 bool addSeparator = false;
54
55 Clear();
56
57 const auto& selection = getToolManager()->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
58
59 if( selection.Size() == 1 )
60 {
61 auto item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
62 const auto& net_attr = item->GetNetAttributes();
63
64 if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) ||
65 ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) )
66 {
67 auto menuEntry = Add( GERBVIEW_ACTIONS::highlightComponent );
68 menuEntry->SetItemLabel( wxString::Format( _( "Highlight Items of Component '%s'" ),
69 net_attr.m_Cmpref ) );
70 addSeparator = true;
71 }
72
73 if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) )
74 {
75 auto menuEntry = Add( GERBVIEW_ACTIONS::highlightNet );
76 menuEntry->SetItemLabel( wxString::Format( _( "Highlight Items of Net '%s'" ),
77 UnescapeString( net_attr.m_Netname ) ) );
78 addSeparator = true;
79 }
80
81 D_CODE* apertDescr = item->GetDcodeDescr();
82
83 if( apertDescr && !apertDescr->m_AperFunction.IsEmpty() )
84 {
85 auto menuEntry = Add( GERBVIEW_ACTIONS::highlightAttribute );
86 menuEntry->SetItemLabel( wxString::Format( _( "Highlight Aperture Type '%s'" ),
87 apertDescr->m_AperFunction ) );
88 addSeparator = true;
89 }
90
91 if( apertDescr )
92 {
93 auto menuEntry = Add( GERBVIEW_ACTIONS::highlightDCode );
94 menuEntry->SetItemLabel( wxString::Format( _( "Highlight DCode D%d" ),
95 apertDescr->m_Num_Dcode ) );
96 addSeparator = true;
97 }
98 }
99
100 if( addSeparator )
101 AppendSeparator();
102
104 }
105
106 ACTION_MENU* create() const override
107 {
108 return new HIGHLIGHT_MENU();
109 }
110};
111
112
114 SELECTION_TOOL( "gerbview.InteractiveSelection" ),
115 m_frame( nullptr )
116{
117}
118
119
121{
123}
124
125
127{
128 std::shared_ptr<HIGHLIGHT_MENU> highlightSubMenu = std::make_shared<HIGHLIGHT_MENU>();
129 highlightSubMenu->SetTool( this );
130 m_menu.RegisterSubMenu( highlightSubMenu );
131
132 m_menu.GetMenu().AddMenu( highlightSubMenu.get() );
133 m_menu.GetMenu().AddSeparator( 1000 );
134
135 getEditFrame<GERBVIEW_FRAME>()->AddStandardSubMenus( m_menu );
136
137 return true;
138}
139
140
142{
143 m_frame = getEditFrame<GERBVIEW_FRAME>();
144
145 if( aReason == TOOL_BASE::MODEL_RELOAD )
146 {
147 // Remove pointers to the selected items from containers
148 // without changing their properties (as they are already deleted
149 // while a new file is loaded)
151 getView()->GetPainter()->GetSettings()->SetHighlight( false );
152 }
153 else
154 {
155 // Restore previous properties of selected items and remove them from containers
157 }
158
159 // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
161 getView()->Add( &m_selection );
162}
163
164
166{
167 // Main loop: keep receiving events
168 while( TOOL_EVENT* evt = Wait() )
169 {
172
173 // on left click, a selection is made, depending on modifiers ALT, SHIFT, CTRL:
174 setModifiersState( evt->Modifier( MD_SHIFT ), evt->Modifier( MD_CTRL ),
175 evt->Modifier( MD_ALT ) );
176
177 // single click? Select single object
178 if( evt->IsClick( BUT_LEFT ) )
179 {
180 selectPoint( evt->Position() );
181 }
182 else if( evt->IsClick( BUT_RIGHT ) )
183 {
184 // right click? if there is any object - show the context menu
185 if( m_selection.Empty() )
186 {
187 selectPoint( evt->Position() );
188 m_selection.SetIsHover( true );
189 }
190
192 }
193 else if( evt->IsDblClick( BUT_MIDDLE ) )
194 {
195 // Middle double click? Do zoom to fit
197 }
198 else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
199 {
201 }
202 else
203 {
204 evt->SetPassEvent();
205 }
206 }
207
208 return 0;
209}
210
211
213{
214 return m_selection;
215}
216
217
219{
220 EDA_ITEM* item = nullptr;
221 GERBER_COLLECTOR collector;
222 EDA_ITEM* model = getModel<EDA_ITEM>();
223
224 collector.Collect( model, { GERBER_LAYOUT_T, GERBER_IMAGE_T, GERBER_DRAW_ITEM_T }, aWhere );
225
226 // Remove unselectable items
227 for( int i = collector.GetCount() - 1; i >= 0; --i )
228 {
229 if( !selectable( collector[i] ) )
230 collector.Remove( i );
231 }
232
233 if( collector.GetCount() > 1 )
234 {
235 doSelectionMenu( &collector );
236
237 if( collector.m_MenuCancelled )
238 return false;
239 }
240
243
244 if( collector.GetCount() == 1 )
245 {
246 item = collector[ 0 ];
247
248 if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
249 {
250 unselect( item );
252 return false;
253 }
254 else
255 {
256 select( item );
258 return true;
259 }
260 }
261
262 return false;
263}
264
265
267{
273}
274
275
277{
279
280 return 0;
281}
282
283
285{
286 std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
287
288 if( items )
289 {
290 // Perform individual selection of each item before processing the event.
291 for( EDA_ITEM* item : *items )
292 select( item );
293
295 }
296
297 return 0;
298}
299
300
302{
303 // Check if there is an item to be selected
304 EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
305
306 if( item )
307 {
308 select( item );
309
310 // Inform other potentially interested tools
312 }
313
314 return 0;
315}
316
317
319{
320 std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
321
322 if( items )
323 {
324 // Perform individual unselection of each item before processing the event
325 for( EDA_ITEM* item : *items )
326 unselect( item );
327
329 }
330
331 return 0;
332}
333
334
336{
337 // Check if there is an item to be selected
338 EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
339
340 if( item )
341 {
342 unselect( item );
343
344 // Inform other potentially interested tools
346 }
347
348 return 0;
349}
350
351
353{
354 if( m_selection.Empty() )
355 return;
356
357 for( EDA_ITEM* item : m_selection )
358 unselectVisually( item );
359
361
362 // Inform other potentially interested tools
364}
365
366
368{
369 GERBVIEW_FRAME* frame = getEditFrame<GERBVIEW_FRAME>();
370 const GERBER_DRAW_ITEM* item = static_cast<const GERBER_DRAW_ITEM*>( aItem );
371 int layer = item->GetLayer();
372
374 return false;
375
376 // We do not want to select items that are in the background
377 if( frame->gvconfig()->m_Display.m_HighContrastMode && layer != frame->GetActiveLayer() )
378 return false;
379
380 return frame->IsLayerVisible( layer );
381}
382
383
385{
386 if( aItem->IsSelected() )
387 return;
388
389 m_selection.Add( aItem );
390 getView()->Add( &m_selection, std::numeric_limits<int>::max() );
391 selectVisually( aItem );
392}
393
394
396{
397 if( !aItem->IsSelected() )
398 return;
399
400 unselectVisually( aItem );
401 m_selection.Remove( aItem );
402
403 if( m_selection.Empty() )
405}
406
407
409{
410 // Move the item's layer to the front
411 int layer = static_cast<GERBER_DRAW_ITEM*>( aItem )->GetLayer();
412 m_frame->SetActiveLayer( layer, true );
413
414 // Hide the original item, so it is shown only on overlay
415 aItem->SetSelected();
416 getView()->Hide( aItem, true );
417
419}
420
421
423{
424 // Restore original item visibility
425 aItem->ClearSelected();
426 getView()->Hide( aItem, false );
427 getView()->Update( aItem, KIGFX::ALL );
428
430}
@ net_highlight_schematic
static TOOL_ACTION updateMenu
Definition: actions.h:171
static TOOL_ACTION zoomFitScreen
Definition: actions.h:98
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:49
TOOL_MANAGER * getToolManager() const
void Clear()
Remove all the entries from the menu (as well as its title).
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:87
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:73
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
bool m_MenuCancelled
Definition: collector.h:237
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:109
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command).
Definition: dcode.h:201
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:191
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
void ClearSelected()
Definition: eda_item.h:121
bool IsSelected() const
Definition: eda_item.h:107
void SetSelected()
Definition: eda_item.h:118
static const TOOL_EVENT ClearedEvent
Definition: actions.h:208
static const TOOL_EVENT SelectedEvent
Definition: actions.h:206
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:207
bool m_HighContrastMode
High contrast mode (dim un-highlighted objects)
@ GBR_NETINFO_NET
print info associated to a net (TO.N attribute)
@ GBR_NETINFO_CMP
print info associated to a component (TO.C attribute)
@ GBR_NETINFO_PAD
print info associated to a flashed pad (TO.P attribute)
Use when the right click button is pressed or when the select tool is in effect.
void Collect(EDA_ITEM *aItem, const std::vector< KICAD_T > &aScanTypes, const VECTOR2I &aRefPos)
Scan an EDA_ITEM using this class's Inspector method, which does the collection.
bool GetLayerPolarity() const
int GetLayer() const
Return the layer this item is on.
const GBR_NETLIST_METADATA & GetNetAttributes() const
static TOOL_ACTION selectionActivate
Activation of the selection tool.
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
static TOOL_ACTION highlightAttribute
static TOOL_ACTION unselectItem
Unselects an item (specified as the event parameter).
static TOOL_ACTION highlightNet
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION highlightComponent
static TOOL_ACTION highlightDCode
static TOOL_ACTION highlightClear
GERBVIEW_SETTINGS * gvconfig() const
bool IsLayerVisible(int aLayer) const
Test whether a given layer is visible.
int GetActiveLayer() const
Return the active layer.
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
change the currently active layer to aLayer and update the GERBER_LAYER_WIDGET.
Selection tool for GerbView, based on the one in Pcbnew.
int SelectItem(const TOOL_EVENT &aEvent)
bool selectable(const EDA_ITEM *aItem) const
Check conditions for an item to be selected.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
bool Init() override
Init() is called once upon a registration of the tool.
int Main(const TOOL_EVENT &aEvent)
The main loop.
int SelectItems(const TOOL_EVENT &aEvent)
int UnselectItems(const TOOL_EVENT &aEvent)
Sets up handlers for various events.
void clearSelection()
Clear the current selection.
void unselect(EDA_ITEM *aItem) override
Take necessary action mark an item as unselected.
void unselectVisually(EDA_ITEM *aItem)
Mark item as selected, but does not add it to the #ITEMS_PICKED_LIST.
bool selectPoint(const VECTOR2I &aWhere)
Select an item pointed by the parameter aWhere.
int UnselectItem(const TOOL_EVENT &aEvent)
int ClearSelection(const TOOL_EVENT &aEvent)
void selectVisually(EDA_ITEM *aItem)
Mark item as selected, but does not add it to the #ITEMS_PICKED_LIST.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
GERBVIEW_SELECTION & GetSelection()
Return the set of currently selected items.
void select(EDA_ITEM *aItem) override
Take necessary action mark an item as selected.
GBR_DISPLAY_OPTIONS m_Display
void update() override
Update menu state stub.
ACTION_MENU * create() const override
< Return an instance of this class. It has to be overridden in inheriting classes.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:316
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:346
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1586
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Temporarily hide the item in the view (e.g.
Definition: view.cpp:1545
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
bool doSelectionMenu(COLLECTOR *aCollector)
int UpdateMenu(const TOOL_EVENT &aEvent)
Update a menu's state based on the current selection.
void setModifiersState(bool aShiftState, bool aCtrlState, bool aAltState)
Set the configuration of m_additive, m_subtractive, m_exclusive_or, m_skip_heuristics from the state ...
virtual void Add(EDA_ITEM *aItem)
Definition: selection.cpp:32
void SetIsHover(bool aIsHover)
Definition: selection.h:76
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.cpp:50
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:90
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:107
bool ToolStackIsEmpty()
Definition: tools_holder.h:128
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
@ MODEL_RELOAD
Model changes (required full reload)
Definition: tool_base.h:80
Generic, UI-independent tool event.
Definition: tool_event.h:156
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:50
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:57
#define _(s)
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:53
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxString UnescapeString(const wxString &aSource)
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:101
@ MD_ALT
Definition: tool_event.h:140
@ MD_CTRL
Definition: tool_event.h:139
@ MD_SHIFT
Definition: tool_event.h:138
@ BUT_MIDDLE
Definition: tool_event.h:129
@ BUT_LEFT
Definition: tool_event.h:127
@ BUT_RIGHT
Definition: tool_event.h:128
@ GERBER_DRAW_ITEM_T
Definition: typeinfo.h:214
@ GERBER_IMAGE_T
Definition: typeinfo.h:215
@ GERBER_LAYOUT_T
Definition: typeinfo.h:213