KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <gal/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 {
45 SetIcon( BITMAPS::net_highlight_schematic );
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 {
171 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
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
191 // Show selection before opening menu
193
195 }
196 else if( evt->IsDblClick( BUT_MIDDLE ) )
197 {
198 // Middle double click? Do zoom to fit
200 }
201 else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
202 {
204 }
205 else
206 {
207 evt->SetPassEvent();
208 }
209 }
210
211 return 0;
212}
213
214
216{
217 return m_selection;
218}
219
220
222{
223 EDA_ITEM* item = nullptr;
224 GERBER_COLLECTOR collector;
225 EDA_ITEM* model = getModel<EDA_ITEM>();
226
227 collector.Collect( model, { GERBER_LAYOUT_T, GERBER_IMAGE_T, GERBER_DRAW_ITEM_T }, aWhere );
228
229 // Remove unselectable items
230 for( int i = collector.GetCount() - 1; i >= 0; --i )
231 {
232 if( !selectable( collector[i] ) )
233 collector.Remove( i );
234 }
235
236 if( collector.GetCount() > 1 )
237 {
238 doSelectionMenu( &collector );
239
240 if( collector.m_MenuCancelled )
241 return false;
242 }
243
246
247 if( collector.GetCount() == 1 )
248 {
249 item = collector[ 0 ];
250
251 if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
252 {
253 unselect( item );
255 return false;
256 }
257 else
258 {
259 select( item );
261 return true;
262 }
263 }
264
265 return false;
266}
267
268
270{
276}
277
278
280{
282
283 return 0;
284}
285
286
288{
289 std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
290
291 if( items )
292 {
293 // Perform individual selection of each item before processing the event.
294 for( EDA_ITEM* item : *items )
295 select( item );
296
298 }
299
300 return 0;
301}
302
303
305{
306 // Check if there is an item to be selected
307 EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
308
309 if( item )
310 {
311 select( item );
312
313 // Inform other potentially interested tools
315 }
316
317 return 0;
318}
319
320
322{
323 std::vector<EDA_ITEM*>* items = aEvent.Parameter<std::vector<EDA_ITEM*>*>();
324
325 if( items )
326 {
327 // Perform individual unselection of each item before processing the event
328 for( EDA_ITEM* item : *items )
329 unselect( item );
330
332 }
333
334 return 0;
335}
336
337
339{
340 // Check if there is an item to be selected
341 EDA_ITEM* item = aEvent.Parameter<EDA_ITEM*>();
342
343 if( item )
344 {
345 unselect( item );
346
347 // Inform other potentially interested tools
349 }
350
351 return 0;
352}
353
354
356{
357 if( m_selection.Empty() )
358 return;
359
360 for( EDA_ITEM* item : m_selection )
361 unselectVisually( item );
362
364
365 // Inform other potentially interested tools
367}
368
369
371{
372 GERBVIEW_FRAME* frame = getEditFrame<GERBVIEW_FRAME>();
373 const GERBER_DRAW_ITEM* item = static_cast<const GERBER_DRAW_ITEM*>( aItem );
374 int layer = item->GetLayer();
375
377 return false;
378
379 // We do not want to select items that are in the background
380 if( frame->gvconfig()->m_Display.m_HighContrastMode && layer != frame->GetActiveLayer() )
381 return false;
382
383 return frame->IsLayerVisible( layer );
384}
385
386
388{
389 if( aItem->IsSelected() )
390 return;
391
392 m_selection.Add( aItem );
393 getView()->Add( &m_selection, std::numeric_limits<int>::max() );
394 selectVisually( aItem );
395}
396
397
399{
400 if( !aItem->IsSelected() )
401 return;
402
403 unselectVisually( aItem );
404 m_selection.Remove( aItem );
405
406 if( m_selection.Empty() )
408}
409
410
412{
413 // Move the item's layer to the front
414 int layer = static_cast<GERBER_DRAW_ITEM*>( aItem )->GetLayer();
415 m_frame->SetActiveLayer( layer, true );
416
417 // Hide the original item, so it is shown only on overlay
418 aItem->SetSelected();
419 getView()->Hide( aItem, true );
420
422}
423
424
426{
427 // Restore original item visibility
428 aItem->ClearSelected();
429 getView()->Hide( aItem, false );
430 getView()->Update( aItem, KIGFX::ALL );
431
433}
static TOOL_ACTION updateMenu
Definition: actions.h:204
static TOOL_ACTION zoomFitScreen
Definition: actions.h:124
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:92
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
Definition: action_menu.cpp:78
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:203
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:193
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
void ForceRefresh()
Force a redraw.
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:118
bool IsSelected() const
Definition: eda_item.h:106
void SetSelected()
Definition: eda_item.h:115
static const TOOL_EVENT ClearedEvent
Definition: actions.h:259
static const TOOL_EVENT SelectedEvent
Definition: actions.h:257
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:258
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:315
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:354
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:1636
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition: view.cpp:1584
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
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:42
void SetIsHover(bool aIsHover)
Definition: selection.h:78
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.cpp:60
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:92
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
bool ToolStackIsEmpty()
Definition: tools_holder.h:125
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
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 (the sheet for a schematic)
Definition: tool_base.h:80
Generic, UI-independent tool event.
Definition: tool_event.h:167
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:460
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, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
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:58
wxString UnescapeString(const wxString &aSource)
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:105
@ MD_ALT
Definition: tool_event.h:144
@ MD_CTRL
Definition: tool_event.h:143
@ MD_SHIFT
Definition: tool_event.h:142
@ BUT_MIDDLE
Definition: tool_event.h:133
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132
@ GERBER_DRAW_ITEM_T
Definition: typeinfo.h:218
@ GERBER_IMAGE_T
Definition: typeinfo.h:219
@ GERBER_LAYOUT_T
Definition: typeinfo.h:217