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 The 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
18 * along with this program. If not, see <https://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 {
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( "common.InteractiveSelection" ),
115 m_frame( nullptr )
116{
117}
118
119
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.get() );
136
137 return true;
138}
139
140
142{
144
145 if( aReason == TOOL_BASE::MODEL_RELOAD || aReason == RESET_REASON::SHUTDOWN )
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)
150 m_selection.Clear();
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 {
170 if( m_frame->ToolStackIsEmpty() )
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
192 m_frame->GetCanvas()->ForceRefresh();
193
194 m_menu->ShowContextMenu( m_selection );
195 }
196 else if( evt->IsDblClick( BUT_MIDDLE ) )
197 {
198 // Middle double click? Do zoom to fit
199 m_toolMgr->RunAction( ACTIONS::zoomFitScreen );
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
219
220
222{
223 EDA_ITEM* item = nullptr;
224 GERBER_COLLECTOR collector;
226
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 );
254 m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
255 return false;
256 }
257 else
258 {
259 select( item );
260 m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
261 return true;
262 }
263 }
264
265 return false;
266}
267
268
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
297 m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
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
314 m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
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
331 m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
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
348 m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
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
363 m_selection.Clear();
364
365 // Inform other potentially interested tools
366 m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
367}
368
369
371{
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
381 && layer != frame->GetActiveLayer() )
382 return false;
383
384 return frame->IsLayerVisible( layer );
385}
386
387
389{
390 if( aItem->IsSelected() )
391 return;
392
393 m_selection.Add( aItem );
394 getView()->Add( &m_selection, std::numeric_limits<int>::max() );
395 selectVisually( aItem );
396}
397
398
400{
401 if( !aItem->IsSelected() )
402 return;
403
404 unselectVisually( aItem );
405 m_selection.Remove( aItem );
406
407 if( m_selection.Empty() )
409}
410
411
413{
414 // Move the item's layer to the front
415 int layer = static_cast<GERBER_DRAW_ITEM*>( aItem )->GetLayer();
416 m_frame->SetActiveLayer( layer, true );
417
418 // Hide the original item, so it is shown only on overlay
419 aItem->SetSelected();
420 getView()->Hide( aItem, true );
421
423}
424
425
427{
428 // Restore original item visibility
429 aItem->ClearSelected();
430 getView()->Hide( aItem, false );
431 getView()->Update( aItem, KIGFX::ALL );
432
434}
@ net_highlight_schematic
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition actions.h:223
static TOOL_ACTION unselectItem
Definition actions.h:224
static TOOL_ACTION selectionActivate
Activation of the selection tool.
Definition actions.h:210
static TOOL_ACTION updateMenu
Definition actions.h:266
static TOOL_ACTION zoomFitScreen
Definition actions.h:138
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
ACTION_MENU(bool isContextMenu, TOOL_INTERACTIVE *aTool=nullptr)
Default constructor.
TOOL_MANAGER * getToolManager() const
Return an instance of TOOL_MANAGER class.
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.
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
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:79
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition collector.h:107
A gerber DCODE (also called Aperture) definition.
Definition dcode.h:76
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command).
Definition dcode.h:210
int m_Num_Dcode
D code value ( >= 10 )
Definition dcode.h:200
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
void ClearSelected()
Definition eda_item.h:153
bool IsSelected() const
Definition eda_item.h:134
void SetSelected()
Definition eda_item.h:150
static const TOOL_EVENT ClearedEvent
Definition actions.h:347
static const TOOL_EVENT SelectedEvent
Definition actions.h:345
static const TOOL_EVENT UnselectedEvent
Definition actions.h:346
GBR_INACTIVE_LAYER_MODE m_InactiveLayerMode
How inactive layers are displayed.
@ 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 highlightAttribute
static TOOL_ACTION highlightNet
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.
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
Sets up handlers for various 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)
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 SELECTION.
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 SELECTION.
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:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:412
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:1892
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
Definition view.cpp:1837
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:227
bool doSelectionMenu(COLLECTOR *aCollector)
bool m_exclusive_or
Items' selection state should be toggled.
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 ...
bool m_subtractive
Items should be removed from selection.
SELECTION_TOOL(const std::string &aName)
bool m_additive
Items should be added to sel (instead of replacing).
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
T * getModel() const
Return the model object if it matches the requested type.
Definition tool_base.h:195
TOOL_MANAGER * m_toolMgr
Definition tool_base.h:220
KIGFX::VIEW * getView() const
Return the instance of KIGFX::VIEW object used in the application.
Definition tool_base.cpp:34
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
@ SHUTDOWN
Tool is being shut down.
Definition tool_base.h:80
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition tool_base.h:76
Generic, UI-independent tool event.
Definition tool_event.h:167
T Parameter() const
Return a parameter assigned to the event.
Definition tool_event.h:484
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).
std::unique_ptr< 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.
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
@ ARROW
Definition cursors.h:42
#define _(s)
@ ALL
All except INITIAL_ADD.
Definition view_item.h:55
wxString UnescapeString(const wxString &aSource)
KIBIS_MODEL * model
@ TA_UNDO_REDO_PRE
This event is sent before undo/redo command is performed.
Definition tool_event.h:102
@ MD_ALT
Definition tool_event.h:141
@ MD_CTRL
Definition tool_event.h:140
@ MD_SHIFT
Definition tool_event.h:139
@ BUT_MIDDLE
Definition tool_event.h:130
@ BUT_LEFT
Definition tool_event.h:128
@ BUT_RIGHT
Definition tool_event.h:129
@ GERBER_DRAW_ITEM_T
Definition typeinfo.h:206
@ GERBER_IMAGE_T
Definition typeinfo.h:207
@ GERBER_LAYOUT_T
Definition typeinfo.h:205
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708